一、SPI
SPI全稱Service Provider Interface,是Java提供的一套用來被第三方實現或者擴展的API,它可以用來啟用框架擴展和替換組件。
整體機制圖如下:
Java SPI 實際上是“基于接口的編程+策略模式+配置文件”組合實現的動態加載機制。
系統設計的各個抽象,往往有很多不同的實現方案,在面向對象的設計里,一般推薦模塊之間基于接口編程,模塊之間不對實現類進行硬編碼。一旦代碼里涉及具體的實現類,就違反了可拔插的原則,如果需要替換一種實現,就需要修改代碼。為了實現在模塊裝配的時候能不在程序里動態指明,這就需要一種服務發現機制。
Java SPI就是提供這樣的一個機制:
為某個接口尋找服務實現的機制。有點類似IOC的思想,就是將裝配的控制權移到程序之外,在模塊化設計中這個機制尤其重要。所以SPI的核心思想就是解耦。
準則
- 當服務提供者提供了接口的一種具體實現后,在jar包的META-INF/services目錄下創建一個以“接口全限定名”為命名的文件,內容為實現類的全限定名;
- 接口實現類所在的jar包放在主程序的classpath中;
- 主程序通過
java.util.ServiceLoader
動態裝載實現模塊,它通過掃描META-INF/services目錄下的配置文件找到實現類的全限定名,并把類加載到JVM; - SPI的實現類必須攜帶一個不帶參數的構造方法。
使用
創建service
public abstract class ApplicationReadyProvider {private static final Log logger = LogFactory.getLog(ApplicationReadyProvider.class);public void launch(ConfigurableApplicationContext applicationContext) {logger.debug("Launch ApplicationReadyProvider: {}", this.getClass().getSimpleName())