SPI机制及serviceLoader源码

为啥

8-10月在找工作,以前埋下的大坑也就没填了,现在有时间继续开搞

去送快递也不错(~﹃~)~zZ
SPI 使用以前可能介绍过,我就不想写了,后面看一下到底介绍过没有。

SPI 介绍

简单来说就是面向接口编程: 根据接口找到对应的service,达到接口和service分离的目的,在其他开发中基本上是一个接口对应一个实现,而这里面就是一个接口对应多个实现,我们根据其他信息找到其中的一个实现。spring 通过Autowired 里面的name可以指定具体实现。

使用

在resources/META-INF/services  下建立一个接口全名的文件,里面内容是其实现。

使用
        ServiceLoader<IMyService> userServiceLoader = ServiceLoader.load(IMyService.class);
        // 2. 创建一个迭代器
        Iterator<IMyService> userServiceIterator = userServiceLoader.iterator();
        while (userServiceIterator.hasNext()){
            IMyService iMyService=userServiceIterator.next();
            iMyService.getName();
        }

如上面的使用所示: 这个是循环获取service的,使用起来比较麻烦。耗费性能

SPI使用场景

Mysql 里面加载驱动的具体实现
Dubbo 里面的扩展对SPI使用

ServiceLoad代码

  • 读取文件:String fullName = PREFIX + service.getName(); , PREFIX 就是META-INF/services/ 因此命名一定要符合,然后就拿fullname 去读取文件里面的class 类目,后面就加载

  • 加载: 迭代器是LazyIterator,在nextService 中实现了加载 类加载c = Class.forName(cn, false, loader);,初始化在S p = service.cast(c.newInstance()); 使用c.newInstance();

上面的命令叫LazyIterator,因为是在迭代器next()->nextService() 里面才去通过文件里面的class名,去加载及示例化的,

缺点线程不安全,而且只能通过 Iterator 形式获取,

dubbo 实现的一种ServiceLoad

ExtensionLoader 类似ServiceLoad,增加了一些东西也是读文件,然后反射生成。


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注