概述
简介
SPI是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。
JDK SPI如何使用
-
- 定义一个接口
package com.test.spi;
public interface Driver {
void getDriver();
}
- 2.实现接口
package com.test.spi.impl;
import com.test.spi.Driver;
public class MysqlDriver implements Driver {
public void getDriver(){
System.out.println("Im mysql");
}
}
package com.test.spi.impl;
import com.test.spi.Driver;
public class PostgreDriver implements Driver {
public void getDriver(){
System.out.println("Im postgre");
}
}
-
- 在META-INF/services/目录里创建一个以 com.test.spi.Driver的文件,这个文件里的内容就是这个接口的具体的实现类。
com.test.spi.impl.MysqlDriver
com.test.spi.impl.PostgreDriver
-
- 使用 ServiceLoader 来加载配置文件中指定的实现
package com.test.spi;
import java.util.ServiceLoader;
import com.test.spi.Driver;
public class SPIDemo {
public static void main(String[] args) {
ServiceLoader<Driver> serviceLoader = ServiceLoader.load(Driver.class);
// 执行不同厂商的业务实现,具体根据业务需求配置
for (Driver driver: serviceLoader) {
driver.getDriver();
}
}
}
输出如下:
Im mysql
Im postgre
Dubbo SPI如何使用
---定义基础应用类
public interface Fruit {}
public class Apple implements Fruit {}
public class Banana implements Fruit{}
----定义SPI类
@SPI("banana")
public interface PlantsWater {
Fruit grant();
@Adaptive
String watering(URL url);
}
public class AppleWater implements PlantsWater {
public Fruit grant() {
return new Apple();
}
public String watering(URL url) {
System.out.println("watering apple");
return "watering finished";
}
}
public class BananaWater implements PlantsWater {
public Fruit grant() {
return new Banana();
}
public String watering(URL url) {
System.out.println("watering banana");
return "watering success";
}
}
----resources文件 org.apache.dubbo.spi.example.PlantsWater
apple=org.apache.dubbo.spi.example.AppleWater
banana=org.apache.dubbo.spi.example.BananaWater
------测试代码内容
public class ExtensionLoaderDemo {
public static void main(String[] args) {
// 首先创建一个模拟用的URL对象
URL url = URL.valueOf("dubbo://192.168.0.101:20880?plants.water=apple");
// 通过ExtensionLoader获取一个PlantsWater对象,getAdaptiveExtension已经加载了所有SPI类
PlantsWater plantsWater = ExtensionLoader.getExtensionLoader(PlantsWater.class)
.getAdaptiveExtension();
// 使用该PlantsWater调用其"自适应标注的"方法,获取调用结果
String result = plantsWater.watering(url);
System.out.println(result);
}
}
-----实际输出内容
十月 11, 2019 7:48:51 下午 org.apache.dubbo.common.logger.LoggerFactory info
信息: using logger: org.apache.dubbo.common.logger.jcl.JclLoggerAdapter
watering apple
watering finished
Process finished with exit code 0
JDK 和 Dubbo SPI简单对比
- JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源
- JDK SPI 如果扩展点加载失败,就失败了,给用户没有任何通知
- 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点
最后
以上就是俏皮音响为你收集整理的JAVA 原生SPI和Dubbo SPI简单使用对比的全部内容,希望文章能够帮你解决JAVA 原生SPI和Dubbo SPI简单使用对比所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复