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