dubbo spi
Dubbo spi目的:获取一个实现类对象
途径:ExtensionLoader.getExtension(String name)|
实现途径:
getExtensionLoader(Class<T> type) 就是为该接口new一个ExtensionLoader,然后缓存起来
getAdaptiveExtension() 获取一个扩展装饰类型的对象,如果没有@Adaptive注解,就会动态创建一个装饰类,例如Protocol&Adative对象
getExtension(String name) 获取一个对象
1. 源码getExtensionLoader阅读:
----------------------------ExtensionLoader.getExtensionLoader(Class<T> type)
ExtensionLoader.getExtensionLoader(Container.class)
-->this.type = type;
-->objectFactory= ExtensionLoader.getExtensionLoader(ExtensionFactory.class)
-->ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension())
-->this.type = type;
-->objectFactory=null
以上代码完成了2个属性的赋值
-
每个ExtensionLoader都包含了2个值type和 objectfactor
Class<?> type // 初始化得到的接口名字 ExtensionFactory objectFactory//初始AdaptiveExtensionFactory[SpiExtensionFactory,Spring]
-
new 一个ExtensionLoader,存储在
ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS
2.阅读getAdaptiveExtension()
adaptive注解在类和方法上的区别:
1.注解在类上:代表人工编码,即实现一个装饰类,例如 ExtesionFactory
2.注解在方法上:代表自动生成和编译一个动态的adaptive类,例如Protocol&Adaptive
--------------------getAdaptiveExtension()
-->getAdaptiveExtension()
-->createAdaptiveExtension()
-->getAdaptiveExtensionClass()
-->getExtensionClasses()//缓存cachedClasses赋值
--> loadExtensionClasses()
-->loadFile
--> createAdaptiveExtensionClass()//自动生成和编译一个动态adptive类,是代理类
-->ExtensionLoader.getExtensionLoader(Compiler.class).getAdaptiveExtension();
-->compiler.compile(code, classLoader);
-->injectExtension()//作用 进入ioc反转 控制,实现动态织入
关于 loadFile的一些细节
目的:通过把配置文件META-INF/dubbo/internal/xxx的 内容,缓存在缓存变量里面
cacheAdaptiveClass://如果当前class含有adative注解就赋值,例如ExtesionFactory,而Protocol就没
cacheWrapperClass//只有当这个class无adative注解,并且构造函数包含目标接口type,例如protocolFilterWrap
cacheActivateClass://剩下的类包含activate注解
cacheName://剩下的类就存在这里
3.阅读getExtension()
---------------------------getExtension(String name)
-->createExtension(String name)
--> getExtensionClasses()
--> injectExtension(T instance) //dubbo的IOC反转控制,就是 从Spring和spi提取对象赋值
--> objectFactory.getExtension(pt, property)
-->SpiExtensionFactory.getExtensionLoader(type,name)
-->ExtensionLoader.getExtensionLoader(type)
-->loader.getAdaptiveExtension();
-->loadFile
-->instance = injectExtension((T)wrapperClass.getConstructor(type).newInstance(instance));//Aop