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 使用及原理分析

經驗總結擴展閱讀