apache dubbo 2.7.3 源代码 - 扩展机制

18 篇文章 0 订阅
11 篇文章 0 订阅
本文深入探讨了Dubbo框架中的扩展类加载机制,包括@Adaptive注解的使用,Wrapper类的作用,以及如何通过ExtensionLoader加载和创建扩展类。解析了缓存Adaptive类和Wrapper类的过程,以及扩展类加载的具体步骤。
摘要由CSDN通过智能技术生成

扩展类,有3种类型
    1、类含有 @Adaptive 注解,那么这个类是 cachedAdaptiveClass
    2、类是包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),那么这个类是 cachedWrapperClasses
    3、普通扩展类型
org.apache.dubbo.common.extension.ExtensionLoader#getExtensionLoader

1、一种扩展类型,有且只能有一个类含有 @Adaptive 注解

private void cacheAdaptiveClass(Class<?> clazz) {
        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());
        }
    }

2、一种扩展类型,可以有多个类含有Wrapper类

private void cacheWrapperClass(Class<?> clazz) {
        if (cachedWrapperClasses == null) {
            cachedWrapperClasses = new ConcurrentHashSet<>();
        }
        cachedWrapperClasses.add(clazz);
    }

3、加载扩展类的过程

private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
        /*
            resourceURL 为所在的配置文件

            如:line == "hessian=org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
                   name="hessian"
                   clazz="org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
            如:line == "http=org.apache.dubbo.rpc.protocol.http.HttpProtocol"
                   name="http"
                   clazz="org.apache.dubbo.rpc.protocol.http.HttpProtocol"
         */
        if (!type.isAssignableFrom(clazz)) {
            throw new IllegalStateException("Error occurred when loading extension class (interface: " +
                    type + ", class line: " + clazz.getName() + "), class "
                    + clazz.getName() + " is not subtype of interface.");
        }
        /*
            1、类含有 @Adaptive 注解,那么这个类是 cachedAdaptiveClass
            2、类是包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),那么这个类是 cachedWrapperClasses
            3、是扩展类
         */
        if (clazz.isAnnotationPresent(Adaptive.class)) { // 适配过的类
            cacheAdaptiveClass(clazz);
        } else if (isWrapperClass(clazz)) { // 被包装过的类
            cacheWrapperClass(clazz);
        } else {
            clazz.getConstructor();
            if (StringUtils.isEmpty(name)) {
                /*
                    1、通过@Extension注解获取名称
                    2、使用类的短名,去除后缀
                 */
                name = findAnnotationName(clazz);
                if (name.length() == 0) {
                    throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
                }
            }

            String[] names = NAME_SEPARATOR.split(name); // 按 , 分割
            if (ArrayUtils.isNotEmpty(names)) {
                cacheActivateClass(clazz, names[0]); // 获取类上的 @Activate 注解
                for (String n : names) {
                    cacheName(clazz, n);
                    /*
                         类放入 extensionClasses

                         extensionClasses = {
                            "hessian" : "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
                            "http" : "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
                         }
                     */
                    saveInExtensionClass(extensionClasses, clazz, n);
                }
            }
        }
    }

4、创建扩展的过程

private T createExtension(String name) {
        /*
            extensionClasses = {
                "hessian" : "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
                "http" : "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
            }

            clazz === "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
            clazz === "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
         */
        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, clazz.newInstance()); // 实例化
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            /*
                通过setter注入属性到扩展
             */
            injectExtension(instance);

            /*
                获取包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),对扩展进行包装
             */
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                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 + ") couldn't be instantiated: " + t.getMessage(), t);
        }
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值