以前研究dubbo的時候就很好奇,裏面各類擴展機制,期間也看過不少關於SPI的機制,今日有緣再度看到有文章總結,故記錄一下,html
首先了解一下 JAVA中SPI簡單的用法java
可參考這篇文章,https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5Amysql
應用場景sql
SPI擴展機制應用場景有不少,好比Common-Logging,JDBC,Dubbo等等。apache
SPI流程:安全
有關組織和公式定義接口標準 多線程
第三方提供具體實現: 實現具體方法, 配置 META-INF/services/${interface_name} 文件 併發
開發者使用post
好比JDBC場景下:線程
首先在Java中定義了接口java.sql.Driver,並無具體的實現,具體的實現都是由不一樣廠商提供。
在MySQL的jar包mysql-connector-java-6.0.6.jar中,能夠找到META-INF/services目錄,該目錄下會有一個名字爲java.sql.Driver的文件,文件內容是com.mysql.cj.jdbc.Driver,這裏面的內容就是針對Java中定義的接口的實現。
一樣在PostgreSQL的jar包PostgreSQL-42.0.0.jar中,也能夠找到一樣的配置文件,文件內容是org.postgresql.Driver,這是PostgreSQL對Java的java.sql.Driver的實現。
不足
1.不能按需加載,須要遍歷全部的實現,並實例化,而後在循環中才能找到咱們須要的實現。若是不想用某些實現類,或者某些類實例化很耗時,它也被載入並實例化了,這就形成了浪費。
2.獲取某個實現類的方式不夠靈活,只能經過 Iterator 形式獲取,不能根據某個參數來獲取對應的實現類。
3.多個併發多線程使用 ServiceLoader 類的實例是不安全的。
如何規避,
針對以上的不足點,咱們在SPI機制選擇時,能夠考慮使用dubbo實現的SPI機制。
具體參考:
http://dubbo.apache.org/zh-cn/blog/introduction-to-dubbo-spi.html