設計模式 - SPI(Service Provider Interface)模式


參考

清幽之地 https://www.jianshu.com/p/3a3edbcd8f24

 

一、什么是SPI

SPI ,全稱為 Service Provider Interface,是一種服務發現機制。它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動加載文件里所定義的類。

這一機制為很多框架擴展提供了可能,比如在Dubbo、JDBC中都使用到了SPI機制。我們先通過一個很簡單的例子來看下它是怎么用的。



二、jdk的SPI

 

代碼

首先,我們需要定義一個接口,SPIService

package com.viewscenes.netsupervisor.spi; public interface SPIService { void execute(); } 

然后,定義兩個實現類,沒別的意思,只輸入一句話。

package com.viewscenes.netsupervisor.spi; public class SpiImpl1 implements SPIService{ public void execute() { System.out.println("SpiImpl1.execute()"); } } ----------------------我是乖巧的分割線---------------------- package com.viewscenes.netsupervisor.spi; public class SpiImpl2 implements SPIService{ public void execute() { System.out.println("SpiImpl2.execute()"); } } 

最后呢,要在ClassPath路徑下配置添加一個文件。文件名字是接口的全限定類名,內容是實現類的全限定類名,多個實現類用換行符分隔。
文件路徑如下:


 
SPI配置文件位置

內容就是實現類的全限定類名:

com.viewscenes.netsupervisor.spi.SpiImpl1
com.viewscenes.netsupervisor.spi.SpiImpl2

測試

然后我們就可以通過ServiceLoader.load或者Service.providers方法拿到實現類的實例。其中,Service.providers包位於sun.misc.Service,而ServiceLoader.load包位於java.util.ServiceLoader

public class Test { public static void main(String[] args) { Iterator<SPIService> providers = Service.providers(SPIService.class); ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class); while(providers.hasNext()) { SPIService ser = providers.next(); ser.execute(); } System.out.println("--------------------------------"); Iterator<SPIService> iterator = load.iterator(); while(iterator.hasNext()) { SPIService ser = iterator.next(); ser.execute(); } } } 

兩種方式的輸出結果是一致的:

SpiImpl1.execute() SpiImpl2.execute() -------------------------------- SpiImpl1.execute() SpiImpl2.execute()


優缺點

優點:將業務代碼和具體實現類解耦,方便擴展。如需增加新邏輯,無需修改主流程,直接在PI配置文件增加實現類的全限定名即可。

缺點:顆粒度不夠細,無法准確定位某一個實現類。要執行就執行所有的實現類。

 

三、Dubbo 的 SPI(對jdk SPI的顆粒度改進)

Dubbo的配置文件

cluster這里可以准確制定一個實現類

SPI配置文件

和jdk只包含實現類的全限定名不同,這里是key value 模式

 

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM