您好,登錄后才能下訂單哦!
SPI是Service Provider Interface的簡稱,是JDK默認(rèn)提供的一種將接口和實(shí)現(xiàn)類進(jìn)行分離的機(jī)制。這種機(jī)制能將接口和實(shí)現(xiàn)進(jìn)行解耦,大大提升系統(tǒng)的可擴(kuò)展性。
SPI機(jī)制約定:當(dāng)一個(gè)Jar包需要提供一個(gè)接口的實(shí)現(xiàn)類時(shí),這個(gè)Jar包需要在META-INF/services/目錄里同時(shí)創(chuàng)建一個(gè)以服務(wù)接口命名的文件。該文件里就是實(shí)現(xiàn)該服務(wù)接口的具體實(shí)現(xiàn)類。而當(dāng)外部程序裝配這個(gè)模塊的時(shí)候,就能通過該Jar包META-INF/services/里的配置文件找到具體的實(shí)現(xiàn)類名,并裝載實(shí)例化,完成模塊的注入。
比如下面的列子,
jcl-over-slf4j
這個(gè)Jar包提供了conmon-logging中
LogFactory
這個(gè)接口的實(shí)現(xiàn)。
文件中的內(nèi)容如下:
JDK為了方便查找 服務(wù)的實(shí)現(xiàn),還提供了一個(gè)工具類:java.util.ServiceLoader。
上面代碼中使用
ServiceLoader
遍歷使用SPI機(jī)制提供的所有
LogFactory
實(shí)現(xiàn)。
SPI機(jī)制的主要應(yīng)用有框架擴(kuò)展和組件的替換等,比如
下面就一步步從定義接口到提供SPI實(shí)現(xiàn)類來演示下SPI機(jī)制具體的使用方式。
step1:先定義一個(gè)接口
<pre class="java" style="margin: 10px 0px; padding: 0px; white-space: pre !important; word-wrap: break-word; position: relative !important;">
Copy
`public interface SaySomething {
String say(String name);
}`</pre>
step2:編寫實(shí)現(xiàn)類
<pre class="java" style="margin: 10px 0px; padding: 0px; white-space: pre !important; word-wrap: break-word; position: relative !important;">
Copy
public class ASaySomething implements SaySomething { @Override public String say(String name) { return "Hi,"+name+", l am A..."; } }
</pre>
step3:在resource下添加META-INFO/services目錄
添加完這個(gè)目錄后,添加一個(gè)以
SaySomething
接口的全限定名為名字的文件,這個(gè)文件的內(nèi)容是你要設(shè)置的具體實(shí)現(xiàn)類。這邊我們就設(shè)置實(shí)現(xiàn)類為上面的
ASaySomething
。
step4:使用SPI機(jī)制
<pre class="java" style="margin: 10px 0px; padding: 0px; white-space: pre !important; word-wrap: break-word; position: relative !important;">
Copy
public static void main(String[] args) { ServiceLoader<SaySomething> loader = ServiceLoader.load(SaySomething.class); loader.forEach(item ->{item.say("csx");}); }
</pre>
在開發(fā)中我們還經(jīng)常會(huì)提到API這個(gè)名詞,下面也總結(jié)下兩者的區(qū)別:
API (Application Programming Interface)在大多數(shù)情況下,都是實(shí)現(xiàn)方制定接口并完成對接口的實(shí)現(xiàn),調(diào)用方僅僅依賴接口調(diào)用,且無權(quán)選擇不同實(shí)現(xiàn)。 從使用人員上來說,API 直接被應(yīng)用開發(fā)人員使用。
SPI (Service Provider Interface)是調(diào)用方來制定接口規(guī)范,提供給外部來實(shí)現(xiàn),調(diào)用方在調(diào)用時(shí)則選擇自己需要的外部實(shí)現(xiàn)。 從使用人員上來說,SPI 被框架擴(kuò)展人員使用。
優(yōu)點(diǎn)
缺點(diǎn)
ServiceLoader
并不是線程安全的。免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。