Dubbo源码解读 —— Dubbo扩展点加载机制
Dubbo源码解读 —— Dubbo扩展点加载机制 1、SPI介绍 2、Java SPI 实现 3、Dubbo Spi 实现 4、Dubbo 中扩展核心类源码解析 5、记录的知识点
1、SPI介绍
-
SPI : Service Provider Interface,种服务发现机制。
-
本质是将接口实现类的全路径名配置在文件中,由服务加载器读取配置文件,加载实现类。
-
可以在运行时,动态为接口替换实现类。
-
可以很容易的通过 SPI 机制为我们的程序提供拓展功能。
-
SPI 机制在第三方框架中也有所应用。
2、Java SPI 实现
-
定义一个接口及对应的方法
public interface IJavaSpiService { Object say(String param); }
-
实现接口定义的方法
public class JavaSpiServiceImpl implements IJavaSpiService { @Override public Object say(String param) { System.out.println("java spi impl "+param); return "java spi impl"; } } public class Java1SpiServiceImpl implements IJavaSpiService { @Override public Object say(String param) { System.out.println("java spi impl "+param); return "java spi impl"; } }
-
数据配置文件
-
ServiceLoader加载具体的实现类
@Test public void javaSpi() { ServiceLoader<IJavaSpiService> spiServices = ServiceLoader.load(IJavaSpiService.class); spiServices.forEach(vo->{ vo.say(vo.getClass().getCanonicalName()); }); }
-
Java Spi
-
JDK标准的SPI会一次性实例化扩展点所有的实现,如果有扩展实现,则初始化很耗时,若没有,也加载,浪费资源。
-
扩展加载失败,则获取不到扩展的名称
-
3、Dubbo Spi 实现
-
Dubbo SPI 是通过键值对的方式进行配置,这样可以按需加载实现类。
-
可以按需加载制定的实现类。
-
Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路径下。
-
Dubbo 实现了AOP 和IOC机制
-
实现源码:
@SPI public interface IDubboSpiService { Object say(); } public class DubboSpiServiceImpl implements IDubboSpiService { @Override public Object say() { System.out.println("dubbo spi impl "); return this.getClass().getCanonicalName(); } } @Test public void dubboSpi() throws Exception { ExtensionLoader<IDubboSpiService> extensionLoader = ExtensionLoader.getExtensionLoader(IDubboSpiService.class); IDubboSpiService dubboSpiServiceImpl = extensionLoader.getExtension("dubboSpiServiceImpl"); System.out.println(dubboSpiServiceImpl.say()); IDubboSpiService iDubboSpiService = extensionLoader.getExtension("dubbo1SpiServiceImpl"); System.out.println(iDubboSpiService.say()); }
4、Dubbo 中扩展核心类源码解析
-
Dubbo 扩展核心类在 dubbo-common模块下,ExtensionLoader,主要方法:getExtension(获得普通扩展类)、getActivateExtension(获得自动激活扩展类)、getAdaptiveExtension(获取自适应扩展类)
-
核心方法getExtension解读:
-
从缓存中先获取目标对象,然后双重锁判断创建扩展实例
-
创建扩展实例:createExtension
-
加载扩展类,解析SPI注解
-
-
Dubbo IOC
Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中.方法:injectExtension
5、记录的知识点
-
核心类(ExtensionLoader)如何创建?
通过工厂类:ExtensionFactory
/** * ExtensionFactory */ @SPI public interface ExtensionFactory { /** * Get extension. * * @param type object type. * @param name object name. * @return object instance. */ <T> T getExtension(Class<T> type, String name); }
-
Dubbo 与 Spring 打通的桥梁是?
具体实现类有:SpringExtensionFactory中有Spring上下文环境ApplicationContext
-
SPI 使用了类缓存,实例缓存,缓存使用ConcurrentMap实现
读源码不易,其读其珍惜~~
来源:oschina
链接:https://my.oschina.net/lihua20103181/blog/3213887