Dubbo內核主要包含SPI、AOP、IOC、Compiler。java
1.spi的設計目標: 編程
面向對象的設計裏,模塊之間是基於接口編程,模塊質檢不對實現類進行硬編碼。一旦代碼裏涉及具體的實現類,就違反了可插拔的原則,若是須要替換一種實現,就須要修改代碼。爲了實如今模塊裝配的時候,不在模塊裏寫死代碼,就須要一種服務發現機制。Java SPI就提供了這樣一種機制:爲某個接口尋找服務實現,有點相似IOC思想,將裝配的控制權移到代碼以外。ide
2.JDK的SPI的默認約定編碼
當服務的提供者提供了一個接口的多種實現時,通常會在jar包的META-INF/services目錄下,建立該接口的同名文件,文件的內容就是該服務接口的具體實現類的全類名。spa
JDK標準的SPI會一次性實例化擴展點全部實現,若是有擴展實現初始化很耗時。但若是沒用上也加載,會很浪費資源。針對這個問題,Dubbo增長了對擴展點IoC和AOP的支持,一個擴展點能夠直接setter注入其它擴展點。設計
1.spi 文件存儲路徑在META-INFdubbointernal 目錄下而且文件名爲接口的全路徑名。即接口文件的全類名。3d
2.每一個spi 文件裏面的格式定義爲: 擴展名=具體的類名,例如 dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtoco。使用時經過key加載(如dubbo),能夠實現部分加載。code
遵循上述第一條第2點,這裏Command爲接口文件,其中StartCommand和ShutdownCommand爲兩個實現類。須要在resources目錄下建META-INF子目錄,在META-INF下建services目錄,而後以接口全路徑做爲文件名建立文件,內容爲接口實現類的全類型名。對象
Command.javablog
package com.dongqiang.soa.spi; /** * Created by qiangdong on 2018/2/2. */ public interface Command { void execute(); }
StartCommand.java
package com.dongqiang.soa.spi; /** * Created by qiangdong on 2018/2/2. */ public class StartCommand implements Command { @Override public void execute() { System.out.println("start command."); } }
ShutdownCommand.java
package com.dongqiang.soa.spi; /** * Created by qiangdong on 2018/2/2. */ public class ShutdownCommand implements Command { @Override public void execute() { System.out.println("ShutdownCommand"); } }
Main類:
package com.dongqiang.soa.spi; import java.util.ServiceLoader; /** * Created by qiangdong on 2018/2/2. */ public class Main { public static void main(String[] args) { ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class); for (Command command : serviceLoader) { command.execute(); } } }