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(); } } }