SPI 簡介java
SPI 全稱爲 (Service Provider Interface) ,是JDK內置的一種服務提供發現機制。 目前有很多框架用它來作服務的擴展發現, 簡單來講,它就是一種動態替換髮現的機制, 舉個例子來講, 有個接口,想運行時動態的給它添加實現,你只須要添加一個實現,然後,把新加的實現,描述給JDK知道就行啦(經過改一個文本文件便可) 公司內部,目前Dubbo框架就基於SPI機制提供擴展功能。sql
簡單示例apache
經過一個簡單例子來講明SPI是如何使用的。 首先經過一張圖來看看,用SPI須要遵循哪些規範,由於spi畢竟是JDK的一種標準。框架
最終的目錄以及結構以下圖所示
........................................................ide
接下來咱們看代碼模塊化
1:首先定義接口和實現類測試
/** * @author xyxsoft@126.com */ public interface HelloService { void sayHello(); }
public class JavaHello implements HelloService{ public void sayHello() { System.out.println("hello:Java"); } }
public class DubboHello implements HelloService{ public void sayHello() { System.out.println("hello:Dubbo"); } }
2:META-INF文件下的HelloService,須要注意的是文件名爲該類的路徑+類名spa
com.xyxsoft.spi.service.impl.JavaHello com.xyxsoft.spi.service.impl.DubboHello
3:test文件下的測試代碼設計
public class SPIMain { public static void main(String[] args) { ServiceLoader<HelloService> loaders = ServiceLoader.load(HelloService.class); for (HelloService in : loaders) { in.sayHello(); } } }
最後的輸出:日誌
hello:Java hello:Dubbo
總之,爲了實如今模塊裝配的時候能不在程序裏動態指明,這就須要一種服務發現機制。java spi就是提供這樣的一個機制:爲某個接口尋找服務實現的機制。有點相似IOC的思想,就是將裝配的控制權移到程序以外,在模塊化設計中這個機制尤爲重要。
其實好多例子都是採用這種模式,好比:1.common-logging和2.jdbc
common-logging,apache最先提供的日誌的門面接口。只有接口,沒有實現。具體方案由各提供商實現,發現日誌提供商是經過掃描 META-INF/services/org.apache.commons.logging.LogFactory配置文件,經過讀取該文件的內容找到日誌提工商實現類。只要咱們的日誌實現裏包含了這個文件,並在文件裏制定 LogFactory工廠接口的實現類便可。
jdbc4.0之前,開發還須要基於Class.forName("xxx")的方式來裝載驅動,jdbc4也基於spi的機制來發現驅動提供商了,能夠經過META-INF/services/java.sql.Driver文件裏指定實現類的方式來暴露驅動提供者。