API:API(Application Programming Interface)表示應用程序編程接口 java
SPI:SPI(Service Provider Interface)表示服務提供商接口
API與SPI的關係
框架提供API及其實現,框架在實現過程當中提供SPI回調機制。SPI是框架的擴展點。若是使用框架方要擴展框架,能夠本身實現SPI並注入框架,因而框架使用方其實也是一個服務提供商。
SPI實現有兩種方式,一種是第三方提供實現,另外一種是應用自身本身提供實現
看一下API/SPI關係圖1,第三方提供商實現了SPI,應用引入第三方提供商的第三方庫
舉例
java中JDBC是一個編程接口,而Driver是一個SPI,同時不一樣數據庫廠商會提供Driver的實現。應用中要使用JDBC編程接口時須要引入第三方數據庫廠商驅動包,第三方廠商提供的驅動包其實就是SPI的實現。 數據庫
框架如何發現SPI?
框架能夠使用java提供的java.util.ServiceLoader類獲得SPI的實現。
如ServiceLoader<PullToolFactory> pullToolFactorys = ServiceLoader.load(PullToolFactory.class);
應用或第三方提供商如何注入SPI實現?
應用或第三方包在jar包的META-INF/services/目錄裏同時建立一個以服務接口命名的文件。該文件裏就是實現該服務接口的具體實現類的徹底限定名。而當框架調用ServiceLoader.load(PullToolFactory.class),就能經過該jar包META-INF/services/裏的配置文件找到具體的實現類名,並裝載實例化,完成SPI實現的注入。
總結:
能夠想象,使用SPI設計,框架能夠很容易引入擴展點,同時應用要擴展框架邏輯也很容易實現。框架可擴展設計能夠基於這個原則進行設計擴展點。
SPI設計的關鍵是程序定義通用的接口好比JDBC,而後不一樣服務提供商根據接口作本身的實現如Driver,而後程序在運行時根據加載到的接口實現不一樣,實現不一樣具體的功能,如操做不一樣的數據庫。編程