dubbo源码解析(二) dubbo spi adaptive实现

上一节分析了ExtensionLoader.getExtensionLoader(Class<T> type)的源码。

 通过ExtensionLoader.getExtensionLoader(Class<T> type).getAdaptiveExtension() 就可以获取接口的一个扩展类。

本节主要分析getAdaptiveExtension()的源码。

首先得出一个结论:针对某个类,如果@Adaptive注解在该类上那么通过getAdaptiveExtension() 就可以获得一个装饰类(人工实现编码);如果注解在方法上就获得一个动态代理类(动态生成和编译代码),例如Protocol$Adaptive对象。

看一下@Adaptive注解的源码

dubbo源码解析(二) dubbo spi adaptive实现

上一节ExtensionLoader的构造函数中objectFactory 是通过

ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()来获取的

dubbo源码解析(二) dubbo spi adaptive实现

看下ExtensionFactory的一个实现类AdaptiveExtensionFactory ,Adaptive注解在类上的

dubbo源码解析(二) dubbo spi adaptive实现

看下Protocol 这个类,Adaptive注解在方法上的

dubbo源码解析(二) dubbo spi adaptive实现


下面分析下ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension()中getAdaptiveExtension()的源码

dubbo源码解析(二) dubbo spi adaptive实现


dubbo源码解析(二) dubbo spi adaptive实现

cachedAdaptiveInstance是ExtensionLoader 中一个缓存的对象

dubbo源码解析(二) dubbo spi adaptive实现

进入createAdaptiveExtension()方法

dubbo源码解析(二) dubbo spi adaptive实现

首先看该方法中的getAdaptiveExtensionClass()

dubbo源码解析(二) dubbo spi adaptive实现

到getExtensionClasses()

dubbo源码解析(二) dubbo spi adaptive实现

cachedClasses 缓存中没有,则通过loadExtensionClasses()获取。

dubbo源码解析(二) dubbo spi adaptive实现


loadfile的部分源码:

dubbo源码解析(二) dubbo spi adaptive实现


dubbo源码解析(二) dubbo spi adaptive实现

关于loadfile的总结
目的:通过把配置文件META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol的内容,存储在缓存变量里面。
cachedAdaptiveClass//如果这个class含有adative注解就赋值,例如ExtensionFactory,而例如Protocol在这个环节是没有的。
cachedWrapperClasses//只有当该class无adative注解,并且构造函数包含目标接口(type)类型,
例如protocol里面的spi就只有ProtocolFilterWrapper和ProtocolListenerWrapper能命中
cachedActivates//剩下的类,包含Activate注解

cachedNames//剩下的类就存储在这里。

回到getAdaptiveExtensionClass方法中,如果cachedAdaptiveClass中有值,说明配置文件中的某一个类含有adaptive注解,则返回该类的实例,getAdaptiveExtension()方法结束。
如果cachedAdaptiveClass中没有值,则调用createAdaptiveExtensionClass();此方法的作用是根据模板代码动态的生成一个类。