Java/Spring/Dubbo三種SPI機(jī)制,誰(shuí)更好?
文章來(lái)源:https://c1n.cn/my8R6

SPI
Java SPI
Java SPI 機(jī)制:

1、自定義接口
//?接口
public?interface?Superman?{
????void?introduce();
}
//?實(shí)現(xiàn)類1
public?class?IronMan?implements?Superman{
????@Override
????public?void?introduce()?{
????????System.out.println("我是鋼鐵俠!");
????}
}
//?實(shí)現(xiàn)類2
public?class?CaptainAmerica?implements?Superman?{
????@Override
????public?void?introduce()?{
????????System.out.println("我是美國(guó)隊(duì)長(zhǎng)!");
????}
}
配置文件:

測(cè)試:
public?static?void?main(String[]?args)?{
????ServiceLoader?serviceLoader?=?ServiceLoader.load(Superman.class);
????System.out.println("Java?SPI:");
????serviceLoader.forEach(Superman::introduce);
}

2、java.sql.Driver 接口

看到這里,你應(yīng)該就知道開頭問(wèn)題的答案了,mysql-connector 的 jar 包中正是通過(guò) SPI 的方式實(shí)現(xiàn)了 java 的 Driver 接口,所以我們的服務(wù)可以在運(yùn)行時(shí)獲取到 mysql 的驅(qū)動(dòng)類,從而連接 mysql 。
Java SPI 原理:
Java SPI 的實(shí)現(xiàn)在 ServiceLoader 類:
這里截取部分代碼,有興趣的同學(xué)自行閱讀。


Java SPI 總結(jié):
Java SPI 機(jī)制:為某個(gè)接口發(fā)現(xiàn)/尋找服務(wù)實(shí)現(xiàn)的機(jī)制。
核心思想:解耦,使得第三方服務(wù)模塊的裝配控制的邏輯與調(diào)用者的業(yè)務(wù)代碼分離。可以根據(jù)實(shí)際業(yè)務(wù)情況進(jìn)行使用或擴(kuò)展。
serviceLoader 只能通過(guò) Iterator 形式遍歷獲取,不能根據(jù)參數(shù)獲取指定的某個(gè)實(shí)現(xiàn)類。
2、資源浪費(fèi)
Spring?SPI

應(yīng)用舉例:
以 dubbo 的使用舉例:


在 spring boot 啟動(dòng)過(guò)程中 ,在 SpringFactoriesLoader.loadFactoryNames(type, classLoader) ?這一步中會(huì)將 EnableAutoConfiguration 的實(shí)現(xiàn)類全部進(jìn)行加載、解析、初始化。
在實(shí)例化 EnableAutoConfiguration 的實(shí)現(xiàn)類時(shí),會(huì)執(zhí)行實(shí)現(xiàn)類 dubboAutoConfiguration 中的具體邏輯,將 dubbo 服務(wù)啟動(dòng)并注冊(cè)到 spring 容器中。
讀取配置文件中的配置項(xiàng)值(配置項(xiàng):DubboConfigConfiguration)生成多個(gè)配置 bean,掃描 dubbo @Service 和?@Reference 注解的類,生成對(duì)應(yīng)的 bean。

Dubbo SPI
特點(diǎn):
1、dubbo SPI 為每個(gè)拓展點(diǎn)(接口)單獨(dú)設(shè)置一個(gè)文件,文件名為接口的全限定名。如org.apache.dubbo.rpc.Filter,org.apache.dubbo.rpc.Protocol,org.apache.dubbo.rpc.cluster.LoadBalance 等。


3、支持 Dubbo 內(nèi)部的依賴注入
Dubbo IOC
通過(guò) setter 方法進(jìn)行依賴注入。Dubbo 首先會(huì)通過(guò)反射獲取到實(shí)例的所有方法,然后再遍歷方法列表,檢測(cè)方法名是否具有 setter 方法特征。若有,則通過(guò) ObjectFactory 獲取依賴對(duì)象,最后通過(guò)反射調(diào)用 setter 方法將依賴設(shè)置到目標(biāo)對(duì)象中。
ExtensionLoader.getExtensionLoader(Filter.class)


配置文件名為接口的全限定名。
由此得到“配置項(xiàng)名稱”到“配置類”的映射關(guān)系表
緩存拓展類對(duì)應(yīng)的 ExtensionLoader 等。
Java、Spring、Dubbo?SPI 對(duì)比

—————END—————
?關(guān)注公眾號(hào):Java后端編程,回復(fù)下面關(guān)鍵字?
要Java學(xué)習(xí)完整路線,回復(fù)??路線?
缺Java入門視頻,回復(fù):?視頻?
要Java面試經(jīng)驗(yàn),回復(fù)??面試?
缺Java項(xiàng)目,回復(fù):?項(xiàng)目?
進(jìn)Java粉絲群:?加群?
PS:如果覺得我的分享不錯(cuò),歡迎大家隨手點(diǎn)贊、在看。
(完) 加我"微信"?獲取一份 最新Java面試題資料 請(qǐng)備注:666,不然不通過(guò)~
最近好文
1、必須推薦的一個(gè)后臺(tái)管理系統(tǒng)
2、無(wú)意中發(fā)現(xiàn)了一位清華妹子的資料庫(kù)!
最近面試BAT,整理一份面試資料《Java面試BAT通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。 獲取方式:關(guān)注公眾號(hào)并回復(fù)?java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。 明天見(??ω??)??
