JavaSPI详解( 四 )

贡献,核心实现如下:
// 获取一个实现类全限定名String cn = nextName;// 加载这个类Class<?> c = Class.forName(cn, false, loader);// 使用反射创建对象c.newInstance()hasNextService()完成堆配置文件的读取,nextService()完成类的加载和对象的创建,这个一切都没有在ServiceLoader创建时完成,这也是体现了延迟Lazy的一个含义
load()与loadInstalled()loadInstalled()load()一样,本质都是创建了一个ServiceLoaderd对象,不同点是使用的加载器不同,load()使用的是Thread.currentThread().getContextClassLoader()当前线程的上下文加载器,loadInstalled()使用的是ExtClassLoader加载器来加载
具体实现如下:
    public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {        ClassLoader cl = ClassLoader.getSystemClassLoader();        ClassLoader prev = null;        while (cl != null) {            prev = cl;            cl = cl.getParent();        }        return ServiceLoader.load(service, prev);    }使用这个方法将只扫描JDK安装目录jre/lib/ext下的jar包中指定的实现,我们应用程序类路径下的实现将会被忽略掉
Java SPI的问题

  • Java SPI虽然使用了懒加载机制,但是其获取一个实现时,需要使用迭代器循环加载所有的实现类
  • 【JavaSPI详解】当需要某一个实现类时,需要通过循环一遍来获取
这个两个问题,在Dubbo实现自己的SPI机制时进行了增强,可以仅加载自己想要的扩展实现 。
为什么SPI机制打破了双亲委派模型 ??想不明白  说不清楚,想明白再补充
参考资料
  • Java SPI 使用及原理分析

经验总结扩展阅读