Java SPI 機制實現解耦與本地化

SPI 是 Java 提供的一種服務加載方式,全名爲 Service Provider Interface,能夠避免在 Java 代碼中寫死服務的提供者,而是經過 SPI 服務加載機制進行服務的註冊和發現。經過這種方式,能夠基於接口編程,實現多個模塊的解耦。java

 

SPI 機制實現解耦

以下的示例展現了經過 ServiceLoader 類加載指定接口的全部服務提供者並進行調用的簡單實現。編程

一、定義接口 test.DirMonitor,包含一個方法 start();ide

二、實現接口 test.DirMonitor,定義兩個實現類 test.ObserverMonitor 和 test.LoopMonitor;oop

三、設置接口的實現類列表。建立目錄 META-INF/services/,新建文件 test.DirMonitor,內容以下:post

test.ObserverMonitor插件

test.LoopMonitorserver

四、在程序中經過 ServiceLoader 類加載 test.DirMonitor 接口的實現類,並遍歷全部實現類,調用 start() 方法;blog

 

 

從上面的示例能夠看出,在代碼中僅僅使用到了接口 test.DirMonitor,並無在代碼中使用到具體實現類。經過這種方法,能夠實現解耦,接口與實現類能夠由不一樣的開發人員實現,編譯到不一樣的 jar 包中,甚至實現插件的定義與開發。接口

 

spi 包的本地化擴展

java.util.spi 包提供了一些抽象類,能夠用於擴展 Java 的本地化服務。本地化 SPI 的使用方法與 ServiceLoader 的 SPI 稍有不一樣,本地化 SPI 的實現須要打包成 jar 包後,放置於運行的 jre/lib/ext 目錄下方能生效。開發

java.util.spi 包提供的抽象類以下所示:

CalendarDataProvider:爲 java.util.Calendar 類的參數提供本地化數據的服務提供者的抽象類;

CalendarNameProvider:爲 java.util.Calendar 類的字段提供本地化名稱的服務提供者的抽象類;

CurrencyNameProvider:爲 java.util.Currency 提供本地化貨幣符號名稱的服務提供者的抽象類;

LocaleNameProvider:爲 java.util.Locale 類提供本地化名稱的服務提供者的抽象類;

LocaleServiceProvider:其餘服務提供者抽象類的基類;

ResourceBundleControlProvider:服務接口,用於提供 java.util.ResourceBundle.Control 的實現類;

TimeZoneNameProvider:爲 java.util.TimeZone 提供本地化時區的服務提供者的抽象類。

 

以 CalendarDataProvider 爲例,該抽象類用於實現本地化的日曆數據。在下面的例子中,CalendarDataProviderSPI 類設置了每週的第一天爲 3,一年中第一週所需的最少天數爲 6。

 

 

 

按照 SPI 的要求,在 META-INF/services/ 下創建 java.util.spi.CalendarDataProvider 文件,並寫入 testspi.CalendarDataProviderSPI。打包爲 jar 後,放置於 jre/lib/ext 目錄後,執行下面的代碼,則打印的數字分別爲 3 和 6,而再也不是默認的 1 和 1。

 

 

總結

Java 經過 SPI 機制爲咱們提供了一種服務發現機制。經過在 META-INF/services/ 目錄下建立以接口全限定名爲名稱的文件,並在文件中每行寫入一個服務提供者的全限定名,Java 能夠發現並建立服務提供者的實例。

經過 ServiceLoader 咱們能夠獲取指定接口的全部服務提供者,並實現接口調用與服務提供者的解耦。經過實現 spi 包的抽象接口,並放置於 jre/lib/ext 目錄下,能夠實現 Java 的本地化。

 

原文地址:Java SPI 機制實現解耦與本地化

相關文章
相關標籤/搜索