SPI 是什么
SPI 全稱 Service Provider Interface,是 Java 提供的一套用來被第三方實現或者擴展的 API,它可以用來啟用框架擴展和替換組件。
整體機制如下圖
Java SPI 實際上是 “基于接口的編程+策略模式+配置文件” 組合實現的動態加載機制。
使用場景
適用于:調用者根據實際使用需要,啟用、擴展、或者替換框架的實現策略
比較常見的例子:
數據庫驅動加載接口實現類的加載,JDBC 加載不同類型數據庫的驅動
日志門面接口實現類加載,SLF4J 加載不同提供商的日志實現類
Spring 中大量使用了 SPI, 比如:對 servlet3.0 規范對 ServletContainerInitializer 的實現、自動類型轉換 Type Conversion SPI (Converter SPI、Formatter SPI) 等
Dubbo 中也大量使用 SPI 的方式實現框架的擴展,不過它對 Java 提供的原生 SPI 做了封裝,允許用戶擴展實現 Filter 接口
使用介紹
要使用 Java SPI,需要遵循如下約定:
當服務提供者提供了接口的一種具體實現后,在 jar 包的 META-INF/services 目錄下創建一個以 “接口全限定名” 為命名的文件,內容為實現類的全限定名;
接口實現類所在的 jar 包放在主程序的 classpath 中;
主程序通過 java.util.ServiceLoder 動態裝載實現模塊,它通過掃描 META-INF/services 目錄下的配置文件找到實現類的全限定名,把類加載到 JVM;
SPI 的實現類必須攜帶一個不帶參數的構造方法;
總結
優點:使用 Java SPI 機制的優勢是實現解耦,使得第三方服務模塊的裝配控制的邏輯與調用者的業務代碼分離,而不是耦合在一起。應用程序可以根據實際業務情況啟用框架擴展或替換框架組件。
缺點:
雖然 ServiceLoader 也算是使用的延遲加載,但是基本只能通過遍歷全部獲取,也就是接口的實現類全部加載并實例化一遍。如果你并不想用某些實現類,它也被加載并實例化了,這就造成了浪費。獲取某個實現類的方式不夠靈活,只能通過 Iterator 形式獲取,不能根據某個參數來獲取對應的實現類。
多個并發多線程使用 ServiceLoader 類的實例是不安全的。
審核編輯:劉清
-
驅動器
+關注
關注
52文章
8236瀏覽量
146364 -
SPI接口
+關注
關注
0文章
258瀏覽量
34382 -
JAVA語言
+關注
關注
0文章
138瀏覽量
20095 -
JVM
+關注
關注
0文章
158瀏覽量
12226 -
解耦控制
+關注
關注
0文章
29瀏覽量
10215
原文標題:淺析 Java - SPI 機制
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論