dubbo为什么不采用jdk的spi?
- jdk标准的spi会一次性实例化扩展点的所有实现,如果有扩展实现初始化很耗时,或者有的扩展实现没有使用到也会被加载,会造成资源浪费。
- dubbo增加了对扩展点的ioc和aop的支持,一个扩展点可以直接setter注入其他的扩展点。
dubbo spi的一些约定:
spi文件的存储路径:
META-INF/dubbo/internal/com.xxx.Protocol
其中com.xxx.Protocal代表文件名,即接口的全路径名。
spi的文件格式定义为:
xxx=com.foo.XxxProtocol yyy=com.foo.YyyProtocol这么定义的原因是:如果扩展实现中的静态属性或方法引用了某些第三方库,而该库又依赖缺失的话,就会导致这个扩展实现初始化失败。在这种情况下,dubbo无法定位失败的扩展id,所以无法精确定位异常信息。
dubbo spi的目的:
获取一个扩展实现类的对象。
ExtensionLoader<T> getExtensionLoader(Class<T> type)
为了获取到扩展实现类的对象,需要先为该接口获取一个extensionLoader,缓存起来,之后通过这个extensionLoader获取到对应的extension。
由extensionLoader获取对应extension主要有两种方式:
/** * Find the extension with the given name.
*/ getExtension(String name)
通过给定的name获取对象。
/** * Get activate extensions. */ getAdaptiveExtension()
获取一个扩展装饰类对象,dubbo的扩展接口有个规则,它所有的实现类中,要么有且仅有一个类被@Adaptive标注,getAdaptiveExtension()返回的就是这个类对象,要么所有的实现类都没有@Adaptive注解,此时,dubbo就动态创建一个代理类并由getAdaptiveExtension()返回。这块后面详细谈论。
下面先讨论extensionLoader的获取
先从dubbo的第一行代码开始:
com.alibaba.dubbo.container.Main.main(args);
从这里的main方法进入,就来到dubbo的Main class,这里定义了一个静态初始化的变量loader,这是dubbo的第一个扩展点,我们从这里开始跟代码,

