Dubbo源码分析

Dubbo的源码分析

接口SimpleExt类的如下
@SPI("impl1")
public interface SimpleExt {
    // @Adaptive example, do not specify a explicit key.
    @Adaptive
    String echo(URL url, String s);

    @Adaptive({"key1", "key2"})
    String yell(URL url, String s);

    // no @Adaptive
    String bang(URL url, int i);
}
 /**
     * 测试默认的扩展名
     * @throws Exception
     */
    @Test
    public void test_getDefaultExtension() throws Exception {
        SimpleExt ext = getExtensionLoader(SimpleExt.class).getDefaultExtension();
        assertThat(ext, instanceOf(SimpleExtImpl1.class));

        String name = getExtensionLoader(SimpleExt.class).getDefaultExtensionName();
        assertEquals("impl1", name);
    }

getExtensionLoader(SimpleExt.class)

 /**
     * EXTENSION_LOADERS 缓存中查找相应的 ExtensionLoader 实例
     *
     * @param type
     * @param <T>
     * @return
     */
    @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 an interface!");
        }
        //判断这个类上是否有SPI接口
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type (" + type +
                    ") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
        }
        /**
         * 从缓存中获取 根据类型获取加载器 org.apache.dubbo.common.extension.ExtensionFactory
         */
        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        /**
         * 取不到创建一个放入EXTENSION_LOADERS中
         */
        if (loader == null) {
            //如果存在key,就不保存(原来是key直接被替换)
            //new ExtensionLoader()去执行默认的构造方法
            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        }
        return loader;
    }
上面的类型是type:(org.apache.dubbo.common.extension.ext1.SimpleExt)
//Dubbo 中一个扩展接口对应一个 ExtensionLoader 实例,该集合缓存了全部 ExtensionLoader 实例,
//其中的 Key 为扩展接口,Value 为加载其扩展实现的 ExtensionLoader 实例
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
根据接口的名称为key,从缓存中获取ExtensionLoader实例;
如果没有缓存中那么就直接执行默认的私有方法
ExtensionLoader.getExtensionLoader(ExtensionFactory.class)
//这里加载的就是org.apache.dubbo.common.extension.ExtensionFactory
通过获取ExtensionLoader获取类型之后;调用getAdaptiveExtension获取ObjectFactory(org.apache.dubbo.common.extension.ExtensionFactory)
public T getAdaptiveExtension() {
        //先从本地缓存中获取Adaptive实例
        Object instance = cachedAdaptiveInstance.get();
        if (instance == null) { //double-check 方式保证线程安全(单实例的实现方式)
            if (createAdaptiveInstanceError != null) { //不为空直接报错
                throw new IllegalStateException("Failed to create adaptive instance: " +
                        createAdaptiveInstanceError.toString(),
                        createAdaptiveInstanceError);
            }
            //加锁判断
            synchronized (cachedAdaptiveInstance) {
                //再次获取
                instance = cachedAdaptiveInstance.get();
                if (instance == null) {
                    try {
                        //获取实例
                        instance = createAdaptiveExtension();
                        //放入本地的缓存
                        cachedAdaptiveInstance.set(instance);
                    } catch (Throwable t) {
                        createAdaptiveInstanceError = t;
                        throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);
                    }
                }
            }
        }

        return (T) instance;
    }
得到ExtensionLoader之后就获取具体的Adaptive的具体实例;
其中就是放在cacheAdaptiveInstance对象中:
Holder<Object> cacheAdaptiveInstance;如果没有缓存本地没有,那么就直接创建

保存cacheAdaptiveInstance的数据结构
public class Holder<T> {
   // volatitle 保证数据的唯一性
    private volatile T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }

}
如果没有实例那么就本地创建createAdaptiveExtension()
private T createAdaptiveExtension() {
        try {
            return injectExtension((T) getAdaptiveExtensionClass().newInstance());
        } catch (Exception e) {
            throw new IllegalStateException("Can't create adaptive extension " + type + ", cause: " + e.getMessage(), e);
        }
    }
继续分析如下
getAdaptiveExtensionClass()源码如下
先调用getExtensionClass()源码,如果获取不到Adaptive那么就调用
createAdaptiveExtensionClass()获取Adaptive
  /**
     * 获取适配器扩展类的字节码文件
     *
     * @return
     */
    private Class<?> getAdaptiveExtensionClass() {
        /**
         * 触发SPI流程的扫描
         */
        getExtensionClasses();
        /**
         * 如果通过上面的步骤可以获取到cachedAdaptiveClass直接返回,如果不行的话,就得考虑自己进行利用动态代理创建一个了
         */
        if (cachedAdaptiveClass != null) {
            return cachedAdaptiveClass;
        }
        /**
         * 利用动态代理创建一个扩展类
         */
        return cachedAdaptiveClass = createAdaptiveExtensionClass();
    }
再继续分析getExtensionClasses()的方法
 private Map<String, Class<?>> getExtensionClasses() {
        Map<String, Class<?>> classes = cachedClasses.get();
        if (classes == null) {
            synchronized (cachedClasses) {
                classes = cachedClasses.get();
                if (classes == null) {
                    //开始加载
                    classes = loadExtensionClasses();
                    cachedClasses.set(classes);
                }
            }
        }
        return classes;
    }
在调用loadExtensionClass()方法
/**
     * synchronized in getExtensionClasses
     * 从缓存中取,也就是说,加载的流程只触发一次,然后放入缓存,后续从缓存取
     */
    private Map<String, Class<?>> loadExtensionClasses() {
        cacheDefaultExtensionName();

        Map<String, Class<?>> extensionClasses = new HashMap<>();
        /**
         * 从下面的地址中加在这个类型的数据的extensionClasses中,地址包括
         * META-INF/dubbo/internal/
         * META-INF/dubbo/
         * META-INF/services/
         */
        for (LoadingStrategy strategy : strategies) {
            System.out.println("获取配置文件下路径---->{}" + strategy.directory());
            System.out.println("获取配置文件名称---->{}" + type.getName());
            loadDirectory(extensionClasses,strategy.directory(),type.getName(),strategy.preferExtensionClassLoader(),strategy.overridden(),strategy.excludedPackages());
            loadDirectory(extensionClasses,strategy.directory(),type.getName().replace("org.apache", "com.alibaba"),strategy.preferExtensionClassLoader(),strategy.overridden(),strategy.excludedPackages());
        }

        return extensionClasses;
    }
先调用
/**
     * extract and cache default extension name if exists
     */
    private void cacheDefaultExtensionName() {
        /**
         * 获取到类型的SPI注解,所以利用SPI扩展点的地方,需要加入SPI注解
         */
        final SPI defaultAnnotation = type.getAnnotation(SPI.class);
        if (defaultAnnotation == null) {
            return;
        }

        String value = defaultAnnotation.value();//判断注解里面是否有值
        if ((value = value.trim()).length() > 0) {
            String[] names = NAME_SEPARATOR.split(value);
            if (names.length > 1) {
                throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
                        + ": " + Arrays.toString(names));
            }
            /**
             * 如果注解中有value,说明有默认的实现,那么将value放到cachedDefaultName中
             */
            if (names.length == 1) {
                cachedDefaultName = names[0];
            }
        }
    }
(1): 获取接口上的注解@SPI的value,就是默认cacheDefaultName
(2): 获取目录下面(META-INF/dubbo/internal,META-INF/services,META-INF/dubbo)查早所有type.getName()声明的类集合
  private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
                               boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
        //命名是这个type类的全限定名称
        String fileName = dir + type; // //META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
        try {
            Enumeration<java.net.URL> urls = null;
            ClassLoader classLoader = findClassLoader();

            // try to load from ExtensionLoader's ClassLoader first
            if (extensionLoaderClassLoaderFirst) {
                ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
                if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
                    urls = extensionLoaderClassLoader.getResources(fileName);
                }
            }

            if (urls == null || !urls.hasMoreElements()) {
                if (classLoader != null) {
                    urls = classLoader.getResources(fileName);
                } else {
                    urls = ClassLoader.getSystemResources(fileName);
                }
            }

            if (urls != null) {
                while (urls.hasMoreElements()) {
                    java.net.URL resourceURL = urls.nextElement();
                    //加载扩展资源
                    loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
                }
            }
        } catch (Throwable t) {
            logger.error("Exception occurred when loading extension class (interface: " +
                    type + ", description file: " + fileName + ").", t);
        }
    }
    private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
                              java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
        try {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    /**
                     * # 之前的内容是我们需要的数据,后面的内容可以认为是注释之类的
                     */
                    final int ci = line.indexOf('#');
                    if (ci >= 0) {
                        line = line.substring(0, ci);
                    }
                    line = line.trim();
                    if (line.length() > 0) {
                        try {
                            String name = null;
                            /**
                             * 看下=的位置,如果有等号,那么=前面的数据是名称,后面的要实现的类的全路径名称
                             */
                            int i = line.indexOf('=');
                            if (i > 0) {
                                name = line.substring(0, i).trim();
                                line = line.substring(i + 1).trim();
                            }
                            if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
                                /**
                                 * 加载解析出来的类的全限定名称
                                 */
                                Class<?> clazz = Class.forName(line, true, classLoader);                  
                                //加载资源
                                loadClass(extensionClasses, resourceURL, clazz, name, overridden);
                            }
                        } catch (Throwable t) {
                            IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
                            exceptions.put(line, e);
                        }
                    }
                }
            }
        } catch (Throwable t) {
            logger.error("Exception occurred when loading extension class (interface: " +
                    type + ", class file: " + resourceURL + ") in " + resourceURL, t);
        }
}

private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
                           boolean overridden) throws NoSuchMethodException {
        /**
         * 判断是新加载clazz是否是type的子类,不是报错
         */
        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.");
        }
        /**
         * 判断这个加载的类上,有没有Adaptive的注解,如果有
         */
        if (clazz.isAnnotationPresent(Adaptive.class)) {
            /**
             * 将此类作为cachedAdaptiveClass
             */
            cacheAdaptiveClass(clazz, overridden);
            /**
             * 如果这个类,没有Adaptive注解
             */
        } else if (isWrapperClass(clazz)) {
            cacheWrapperClass(clazz);// 处理Wrapper类
        } else {
            clazz.getConstructor(); // 扩展实现类必须有无参构造函数
            if (StringUtils.isEmpty(name)) {
                name = findAnnotationName(clazz);
                if (name.length() == 0) {
                    throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
                }
            }
            // 兜底:SPI配置文件中未指定扩展名称,则用类的简单名称作为扩展名(略)
            String[] names = NAME_SEPARATOR.split(name);
            if (ArrayUtils.isNotEmpty(names)) {
                // 将包含@Activate注解的实现类缓存到cachedActivates集合中
                cacheActivateClass(clazz, names[0]);
                for (String n : names) {
                    // 在cachedNames集合中缓存实现类->扩展名的映射
                    cacheName(clazz, n);
                    // 在cachedClasses集合中缓存扩展名->实现类的映射
                    saveInExtensionClass(extensionClasses, clazz, n, overridden);
                }
            }
        }
    }
查找有Adaptive注解的类,就是要找的Adaptive类
如果没有Adaptive类,那么尝试能否通过Wrapper方式获取类,如果可以获取,那么缓存到Set<Class<?>> cachedWrapperClasses;中

创建Adaptive扩展类

private Class<?> getAdaptiveExtensionClass() {
        /**
         * 触发SPI流程的扫描
         */
        getExtensionClasses();
        /**
         * 如果通过上面的步骤可以获取到cachedAdaptiveClass直接返回,如果不行的话,就得考虑自己进行利用动态代理创建一个了
         */
        if (cachedAdaptiveClass != null) {
            return cachedAdaptiveClass;
        }
        /**
         * 利用动态代理创建一个扩展类
         */
        return cachedAdaptiveClass = createAdaptiveExtensionClass();
    }
通过createAdaptiveExtensionClassCode()得到用于生成Adaptive扩展类的源代码code
得到类加载器ClassLoader
通过扩展机制得到编译器(默认用JavassistCompiler)将扩展类源代码code编译成字节码从而      得到Adaptive类
private Class<?> createAdaptiveExtensionClass() {
    String code = createAdaptiveExtensionClassCode();
    ClassLoader classLoader = findClassLoader();
    com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
    return compiler.compile(code, classLoader);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值