dubbo学习笔记 九 dubbo-common之动态扩展extension
来源:互联网 发布:网络机柜理线路图 编辑:程序博客网 时间:2024/06/11 05:10
extension 动态扩展包,dubbo里面有很多 @SPI @Activate @Adaptive 注解, 同时也有许多配置文件。
如下面的路径
private static final String SERVICES_DIRECTORY = "META-INF/services/"; private static final String DUBBO_DIRECTORY = "META-INF/dubbo/"; private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";
那么dubbo 是如何利用这些配置和 注解做的动态扩展的呢? 我们得先学两个类
ExtensionFactory 和 ExtensionLoader
ExtensionFactory
这个类只有一个接口,输入class 返回一个instance
@SPIpublic interface ExtensionFactory { /** * Get extension. * * @param type object type. * @param name object name. * @return object instance. */ <T> T getExtension(Class<T> type, String name);}
它有三个实现类
SpringExtensionFactory
这个就是从 ApplicationContext 获取个bean。@SuppressWarnings("unchecked") public <T> T getExtension(Class<T> type, String name) { for (ApplicationContext context : contexts) { if (context.containsBean(name)) { Object bean = context.getBean(name); if (type.isInstance(bean)) { return (T) bean; } } } return null; }
AdaptiveExtensionFactory
适配factory,从factorys中获取instance 先从spi再从spring
public AdaptiveExtensionFactory() { ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class); List<ExtensionFactory> list = new ArrayList<ExtensionFactory>(); for (String name : loader.getSupportedExtensions()) { list.add(loader.getExtension(name)); } factories = Collections.unmodifiableList(list); } public <T> T getExtension(Class<T> type, String name) { for (ExtensionFactory factory : factories) { T extension = factory.getExtension(type, name); if (extension != null) { return extension; } } return null; }
SpiExtensionFactory
用ExtensionLoader来动态扩展,获取instance
public <T> T getExtension(Class<T> type, String name) { if (type.isInterface() && type.isAnnotationPresent(SPI.class)) { ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type); if (loader.getSupportedExtensions().size() > 0) { return loader.getAdaptiveExtension(); } } return null; }
ExtensionLoader
终于来这个类。先看下他动态生成的instance
public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {public void destroy() {throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public int getDefaultPort() {throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0)throws com.alibaba.dubbo.rpc.RpcException {if (arg0 == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");if (arg0.getUrl() == null)throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url("+ url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.export(arg0);}public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1)throws com.alibaba.dubbo.rpc.RpcException {if (arg1 == null)throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg1;String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());if (extName == null)throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url("+ url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.refer(arg0, arg1);}}
extensionLoader动态加载配置?
Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>(); loadFile(extensionClasses, DUBBO_INTERNAL_DIRECTORY); loadFile(extensionClasses, DUBBO_DIRECTORY); loadFile(extensionClasses, SERVICES_DIRECTORY); return extensionClasses;
@Adaptive 的动态生成 wrapper的来进行包装
if (clazz.isAnnotationPresent(Adaptive.class)) { if(cachedAdaptiveClass == null) { cachedAdaptiveClass = clazz; } else if (! cachedAdaptiveClass.equals(clazz)) { throw new IllegalStateException("More than 1 adaptive class found: " + cachedAdaptiveClass.getClass().getName() + ", " + clazz.getClass().getName()); } } else { try { clazz.getConstructor(type); Set<Class<?>> wrappers = cachedWrapperClasses; if (wrappers == null) { cachedWrapperClasses = new ConcurrentHashSet<Class<?>>(); wrappers = cachedWrapperClasses; } wrappers.add(clazz);
extensionLoader会操作哪些类?
必须是个接口,且必须有SPI注解
@SuppressWarnings("unchecked") public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) { if (type == null) throw new IllegalArgumentException("Extension type == null"); if(!type.isInterface()) { throw new IllegalArgumentException("Extension type(" + type + ") is not interface!"); } if(!withExtensionAnnotation(type)) { throw new IllegalArgumentException("Extension type(" + type + ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!"); } ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); if (loader == null) { EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type)); loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); } return loader; }
extensionLoader怎么创造扩展?
private T createExtension(String name) { Class<?> clazz = getExtensionClasses().get(name); if (clazz == null) { throw findException(name); } try { T instance = (T) EXTENSION_INSTANCES.get(clazz); if (instance == null) { EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance()); instance = (T) EXTENSION_INSTANCES.get(clazz); } injectExtension(instance); Set<Class<?>> wrapperClasses = cachedWrapperClasses; if (wrapperClasses != null && wrapperClasses.size() > 0) { for (Class<?> wrapperClass : wrapperClasses) { instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance)); } } return instance; } catch (Throwable t) { throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type + ") could not be instantiated: " + t.getMessage(), t); } }
0 0
- dubbo学习笔记 九 dubbo-common之动态扩展extension
- dubbo学习笔记 八 dubbo-common
- dubbo extension扩展点 源代码
- dubbo源码阅读笔记--动态扩展
- dubbo关于filter组装,extension扩展逻辑.
- dubbo学习笔记 十一 dubbo-rpc之模块
- dubbo学习笔记
- 阿里Dubbo学习笔记
- dubbo-学习笔记
- dubbo入门学习笔记
- dubbo学习笔记
- dubbo 学习笔记
- dubbo学习笔记
- dubbo学习概要笔记
- Dubbo入门学习笔记
- Dubbo 学习笔记
- DUBBO学习笔记
- dubbo 学习笔记
- pig-0.11.1安装安装部署
- swoole深入学习 1. swoole初始
- 1015. 德才论 (25)
- Android 数据存储ContentProvider(类容提供者)之对外提供数据修改
- 基于opencv视频中运动目标标定
- dubbo学习笔记 九 dubbo-common之动态扩展extension
- swift语言的学习笔记三(闭包-匿名函数)
- 基于Python的Selenium自动化— 实现验证码截取并识别
- 七大排序算法之快速排序
- swoole深入学习 2. tcp Server和tcp Client
- 图片资源
- PHP实现的QQ空间g_tk加密算法
- dubbo学习笔记 十 dubbo-rpc
- swift语言的学习笔记四(类对象,函数)