看过dubbo开发者文档就会发现,dubbo中组件的扩展都需要你在META-INF/dubbo目录下新增一个以对应组件接口名为文件名,自定义扩展名为内容的文本文件。 那dubbo是如何加载这些扩展点又是如何匹配这些扩展点的。
spi类加载
在dubbo内部,所有扩展点的加载以及映射都是通过ExtensionLoader来实现的,每类组件都会拥有一个相应的ExtensionLoader实例,该实例会读取所有META-INF/dubbo目录下所有以该组件全路径命名的文件。
ExtensionLoader以<name,class>方式存储该组件的扩展点实例。
Adaptive Extension
dubbo中每个组件都需要有一个并且是唯一的一个激活的扩展点。给类增加@Adaptive
注解以标示该扩展为默认扩展点。
同时,但一个组件没有默认自定义的默认扩展点时,dubbo为了保证激活扩展点不为空的情况,会通过变成方式拼接源代码,使用javassist编译生成默认的激活扩展点(接口方法上添加@Adaptive
注解才会被扩展,否则调用会直接报错)。
目标扩展点的获取
更多的情况下,dubbo都是获取他通过代码生成的默认激活扩展点,在实际调用时,通过配置和入参,获取实际的扩展点并调用相应的方法。
从可获取URL的方法参数以及接口方法上@Adaptive
注解的value(标示URL对应属性,如@Adaptive("protocol")
则表明URL的protocol的值为扩展点名)来匹配实际的扩展点名,然后从ExtensionLoader中获取对应的扩展,以实现组件的自定义扩展。