每个ExtensionLoader实例只负责加载一个特定扩大点实现
每个扩大点对应最多只有一个ExtensionLoader实例
对于每个扩大点实现,最多只会有一个实例
一个扩大点实现能够对应多个名称(逗号分隔)
每个扩大点最多只能有一个被AdaptiveExtension
每个扩大点能够有多个可主动激活的扩大点实现(应用@Activate注解)
因为每个扩大点实现最多只有一个实例,因而扩大点实现应保障线程平安
如果扩大点有多个Wrapper,那么最终其执行的程序不确定(外部应用ConcurrentHashSet存储)
getExtension办法:

    public T getExtension(String name) {    if (name == null || name.length() == 0)        throw new IllegalArgumentException("Extension name == null");    if ("true".equals(name)) {        return getDefaultExtension();    }    // 先从缓存获取    Holder<Object> holder = cachedInstances.get(name);    if (holder == null) {        cachedInstances.putIfAbsent(name, new Holder<Object>());        holder = cachedInstances.get(name);    }    Object instance = holder.get();    if (instance == null) {        synchronized (holder) {            instance = holder.get();            if (instance == null) {                // 构建instance                instance = createExtension(name);                holder.set(instance);            }        }    }    return (T) instance;}

createExtension办法:

private T createExtension(String name) {    // 获取class文件    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);        }        // IOC填充对象        injectExtension(instance);        Set<Class<?>> wrapperClasses = cachedWrapperClasses;        // AOP切片实现        if (wrapperClasses != null && !wrapperClasses.isEmpty()) {                // 通过含参的构造方法将SPI实例(依据指定名字创立好的)注入进去                // 注入胜利并创立好实例之后会把这个组装好的Wrapper实例返回                // 这样循环到下一个Wrapper类时其实注入的是上一个Wrapper类实例                // 这样导致先注入的后执行            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);    }}

injectExtension办法:

    private T injectExtension(T instance) {    try {        if (objectFactory != null) {            // 遍历指标类上的所有办法            for (Method method : instance.getClass().getMethods()) {                // 查看办法是否已set 结尾,且办法只有一个参数,且办法拜访级别是public                if (method.getName().startsWith("set")                        && method.getParameterTypes().length == 1                        && Modifier.isPublic(method.getModifiers())) {                    /**                     * Check {@link DisableInject} to see if we need auto injection for this property                     */                    // 如果办法有 DisableInject 注解润饰,则疏忽                    if (method.getAnnotation(DisableInject.class) != null) {                        continue;                    }                    // 获取 setter 办法参数类型                    Class<?> pt = method.getParameterTypes()[0];                    if (ReflectUtils.isPrimitives(pt)) {                        continue;                    }                    try {                        // 获取属性名,比方 setName 办法对应属性名 name                        String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";                        // 从 ObjectFactory 中获取依赖对象                        Object object = objectFactory.getExtension(pt, property);                        if (object != null) {                            // 通过反射调用 setter 办法设置依赖                            method.invoke(instance, object);                        }                    } catch (Exception e) {                        logger.error("Failed to inject via method " + method.getName()                                + " of interface " + type.getName() + ": " + e.getMessage(), e);                    }                }            }        }    } catch (Exception e) {        logger.error(e.getMessage(), e);    }    return instance;}

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;}

loadExtensionClasses办法:

    private Map<String, Class<?>> loadExtensionClasses() {    // 加载默认的实现    final SPI defaultAnnotation = type.getAnnotation(SPI.class);    if (defaultAnnotation != null) {        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));            }            if (names.length == 1) cachedDefaultName = names[0];        }    }    // 从META-INF/dubbo/internal/、META-INF/dubbo/、META-INF/services/ 这三个指定的文件夹加加载此类型的实现类    Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();    loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);    loadDirectory(extensionClasses, DUBBO_DIRECTORY);    loadDirectory(extensionClasses, SERVICES_DIRECTORY);    return extensionClasses;}

loadDirectory办法:

    private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir) {    String fileName = dir + type.getName();    try {        Enumeration<java.net.URL> urls;        ClassLoader classLoader = findClassLoader();         // 依据文件名加载所有的同名文件        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);            }        }    } catch (Throwable t) {        logger.error("Exception when load extension class(interface: " +                type + ", description file: " + fileName + ").", t);    }}

loadResource办法:

private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL) {    try {        BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "utf-8"));        try {            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) {                            // 依据读取的内容 应用Class.forName加载对应类                            loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name);                        }                    } 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);                    }                }            }        } finally {            reader.close();        }    } catch (Throwable t) {        logger.error("Exception when load extension class(interface: " +                type + ", class file: " + resourceURL + ") in " + resourceURL, t);    }}

loadClass办法:

    private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {    if (!type.isAssignableFrom(clazz)) {        throw new IllegalStateException("Error when load extension class(interface: " +                type + ", class line: " + clazz.getName() + "), class "                + clazz.getName() + "is not subtype of interface.");    }    if (clazz.isAnnotationPresent(Adaptive.class)) {        if (cachedAdaptiveClass == null) { // 如果类被Adaptive润饰,设置cachedAdaptiveClass缓存            cachedAdaptiveClass = clazz;        } else if (!cachedAdaptiveClass.equals(clazz)) {            throw new IllegalStateException("More than 1 adaptive class found: "                    + cachedAdaptiveClass.getClass().getName()                    + ", " + clazz.getClass().getName());        }    } else if (isWrapperClass(clazz)) { // 如果是wrapper类,设置wrapper的缓存        Set<Class<?>> wrappers = cachedWrapperClasses;        if (wrappers == null) {            cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();            wrappers = cachedWrapperClasses;        }        wrappers.add(clazz);    } else {    // 一般的spi实现类        clazz.getConstructor();        if (name == null || name.length() == 0) {            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 (names != null && names.length > 0) {            Activate activate = clazz.getAnnotation(Activate.class);            if (activate != null) { //如果有activate 退出缓存 如果对应多个名字 只会采纳第一个名字                cachedActivates.put(names[0], activate);            }            for (String n : names) {                if (!cachedNames.containsKey(clazz)) {                    cachedNames.put(clazz, n);                }                Class<?> c = extensionClasses.get(n);                if (c == null) { // 将名字->类退出缓存                    extensionClasses.put(n, clazz);                } else if (c != clazz) {                    throw new IllegalStateException("Duplicate extension " + type.getName() + " name " + n + " on " + c.getName() + " and " + clazz.getName());                }            }        }    }}

///
///
getAdaptiveExtension办法:

    public T getAdaptiveExtension() {    Object instance = cachedAdaptiveInstance.get();    // 双重查看 加锁创立缓存    if (instance == null) {        if (createAdaptiveInstanceError == null) {            synchronized (cachedAdaptiveInstance) {                instance = cachedAdaptiveInstance.get();                if (instance == null) {                    try {                        // 缓存没有 创立                        instance = createAdaptiveExtension();                        cachedAdaptiveInstance.set(instance);                    } catch (Throwable t) {                        createAdaptiveInstanceError = t;                        throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);                    }                }            }        } else {            throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);        }    }    return (T) instance;}

createAdaptiveExtension办法:

    // 调用 getAdaptiveExtensionClass 办法获取自适应拓展 Class 对象    // 通过反射进行实例化    // 调用injectExtension办法向拓展实例中注入依赖    private T createAdaptiveExtension() {    try {        return injectExtension((T) getAdaptiveExtensionClass().newInstance());    } catch (Exception e) {        throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);    }}

getAdaptiveExtensionClass办法:

    private Class<?> getAdaptiveExtensionClass() {    // 先获取此type的所有实现类的class    getExtensionClasses();    if (cachedAdaptiveClass != null) { //如果有 Adaptive润饰的实现类 间接返回        return cachedAdaptiveClass;    }    // 构建代理类    return cachedAdaptiveClass = createAdaptiveExtensionClass();}

createAdaptiveExtensionClass办法:

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();    // 应用javassist 编译为class    return compiler.compile(code, classLoader);}

createAdaptiveExtensionClassCode办法:

    private String createAdaptiveExtensionClassCode() {    StringBuilder codeBuilder = new StringBuilder();    Method[] methods = type.getMethods();    boolean hasAdaptiveAnnotation = false;    // 第一局部    // 如果没有Adaptive润饰办法会抛异样    for (Method m : methods) {        if (m.isAnnotationPresent(Adaptive.class)) {            hasAdaptiveAnnotation = true;            break;        }    }    // no need to generate adaptive class since there's no adaptive method found.    if (!hasAdaptiveAnnotation)        throw new IllegalStateException("No adaptive method on extension " + type.getName() + ", refuse to create the adaptive class!");     // 第二局部    // 生成package、import等代码    codeBuilder.append("package ").append(type.getPackage().getName()).append(";");    codeBuilder.append("\nimport ").append(ExtensionLoader.class.getName()).append(";");    codeBuilder.append("\npublic class ").append(type.getSimpleName()).append("$Adaptive").append(" implements ").append(type.getCanonicalName()).append(" {");    //第三局部    // 如果Adaptive没有润饰办法,此代理类不会构建具体的办法    // Adaptive润饰的办法必须参数含有URL或者某个参数有getURL办法    for (Method method : methods) {        Class<?> rt = method.getReturnType();        Class<?>[] pts = method.getParameterTypes();        Class<?>[] ets = method.getExceptionTypes();        Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);        StringBuilder code = new StringBuilder(512);        if (adaptiveAnnotation == null) {            code.append("throw new UnsupportedOperationException(\"method ")                    .append(method.toString()).append(" of interface ")                    .append(type.getName()).append(" is not adaptive method!\");");        } else {            int urlTypeIndex = -1;            for (int i = 0; i < pts.length; ++i) {                if (pts[i].equals(URL.class)) {                    urlTypeIndex = i;                    break;                }            }            // found parameter in URL type            if (urlTypeIndex != -1) {                // Null Point check                String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"url == null\");",                        urlTypeIndex);                code.append(s);                s = String.format("\n%s url = arg%d;", URL.class.getName(), urlTypeIndex);                code.append(s);            }            // did not find parameter in URL type            else {                String attribMethod = null;                // find URL getter method                LBL_PTS:                for (int i = 0; i < pts.length; ++i) {                    Method[] ms = pts[i].getMethods();                    for (Method m : ms) {                        String name = m.getName();                        if ((name.startsWith("get") || name.length() > 3)                                && Modifier.isPublic(m.getModifiers())                                && !Modifier.isStatic(m.getModifiers())                                && m.getParameterTypes().length == 0                                && m.getReturnType() == URL.class) {                            urlTypeIndex = i;                            attribMethod = name;                            break LBL_PTS;                        }                    }                }                if (attribMethod == null) {                    throw new IllegalStateException("fail to create adaptive class for interface " + type.getName()                            + ": not found url parameter or url attribute in parameters of method " + method.getName());                }                // Null point check                String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"%s argument == null\");",                        urlTypeIndex, pts[urlTypeIndex].getName());                code.append(s);                s = String.format("\nif (arg%d.%s() == null) throw new IllegalArgumentException(\"%s argument %s() == null\");",                        urlTypeIndex, attribMethod, pts[urlTypeIndex].getName(), attribMethod);                code.append(s);                s = String.format("%s url = arg%d.%s();", URL.class.getName(), urlTypeIndex, attribMethod);                code.append(s);            }             // 第四局部            // 生成类对应的名字            String[] value = adaptiveAnnotation.value();            // value is not set, use the value generated from class name as the key            if (value.length == 0) { // 如果注解没有给出名字 就用类名用.拼接 eg: CatST --> cat.s.t                char[] charArray = type.getSimpleName().toCharArray();                StringBuilder sb = new StringBuilder(128);                for (int i = 0; i < charArray.length; i++) {                    if (Character.isUpperCase(charArray[i])) {                        if (i != 0) {                            sb.append(".");                        }                        sb.append(Character.toLowerCase(charArray[i]));                    } else {                        sb.append(charArray[i]);                    }                }                value = new String[]{sb.toString()};            }            // Invocation参数解决            boolean hasInvocation = false;            for (int i = 0; i < pts.length; ++i) {                if (pts[i].getName().equals("com.alibaba.dubbo.rpc.Invocation")) {                    // Null Point check                    String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"invocation == null\");", i);                    code.append(s);                    s = String.format("\nString methodName = arg%d.getMethodName();", i);                    code.append(s);                    hasInvocation = true;                    break;                }            }            String defaultExtName = cachedDefaultName;            String getNameCode = null;            for (int i = value.length - 1; i >= 0; --i) {                if (i == value.length - 1) {                    if (null != defaultExtName) {                        if (!"protocol".equals(value[i]))                            if (hasInvocation)                                getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);                            else                                getNameCode = String.format("url.getParameter(\"%s\", \"%s\")", value[i], defaultExtName);                        else                            getNameCode = String.format("( url.getProtocol() == null ? \"%s\" : url.getProtocol() )", defaultExtName);                    } else {                        if (!"protocol".equals(value[i]))                            if (hasInvocation)                                getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);                            else                                getNameCode = String.format("url.getParameter(\"%s\")", value[i]);                        else                            getNameCode = "url.getProtocol()";                    }                } else {                    if (!"protocol".equals(value[i]))                        if (hasInvocation)                            getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);                        else                            getNameCode = String.format("url.getParameter(\"%s\", %s)", value[i], getNameCode);                    else                        getNameCode = String.format("url.getProtocol() == null ? (%s) : url.getProtocol()", getNameCode);                }            }            code.append("\nString extName = ").append(getNameCode).append(";");            // check extName == null?            String s = String.format("\nif(extName == null) " +                            "throw new IllegalStateException(\"Fail to get extension(%s) name from url(\" + url.toString() + \") use keys(%s)\");",                    type.getName(), Arrays.toString(value));            code.append(s);                s = String.format("\n%s extension = (%<s)%s.getExtensionLoader(%s.class).getExtension(extName);",                    type.getName(), ExtensionLoader.class.getSimpleName(), type.getName());            code.append(s);            // 第五局部 生成返回类型            // return statement            if (!rt.equals(void.class)) {                code.append("\nreturn ");            }            // 第六局部 生成拓展加载与指标办法调用逻辑 大抵逻辑就是依据获取到的name获取对应的实现类,而后调用实现类的办法            s = String.format("extension.%s(", method.getName());            code.append(s);            for (int i = 0; i < pts.length; i++) {                if (i != 0)                    code.append(", ");                code.append("arg").append(i);            }            code.append(");");        }        codeBuilder.append("\npublic ").append(rt.getCanonicalName()).append(" ").append(method.getName()).append("(");        for (int i = 0; i < pts.length; i++) {            if (i > 0) {                codeBuilder.append(", ");            }            codeBuilder.append(pts[i].getCanonicalName());            codeBuilder.append(" ");            codeBuilder.append("arg").append(i);        }        codeBuilder.append(")");        if (ets.length > 0) {            codeBuilder.append(" throws ");            for (int i = 0; i < ets.length; i++) {                if (i > 0) {                    codeBuilder.append(", ");                }                codeBuilder.append(ets[i].getCanonicalName());            }        }        codeBuilder.append(" {");        codeBuilder.append(code.toString());        codeBuilder.append("\n}");    }    codeBuilder.append("\n}");    if (logger.isDebugEnabled()) {        logger.debug(codeBuilder.toString());    }    return codeBuilder.toString();}

///
///
getActivateExtension办法:

    public List<T> getActivateExtension(URL url, String[] values, String group) {    List<T> exts = new ArrayList<T>();    List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);    if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {        getExtensionClasses();        for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {            String name = entry.getKey();            Activate activate = entry.getValue();            // 依据group过滤            if (isMatchGroup(group, activate.group())) {                T ext = getExtension(name);                if (!names.contains(name) // 避免反复退出 上面就是依据指定name寻找对应的实现类                        && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)                        && isActive(activate, url)) { // 检测value和url  如果类上的Activate(value={"bigKey"},group = "q") 制订了value,那么url中如果不含有此key的参数就匹配不上                    exts.add(ext);                }            }        }        Collections.sort(exts, ActivateComparator.COMPARATOR);    }    List<T> usrs = new ArrayList<T>();    // 依据name寻找实现类    for (int i = 0; i < names.size(); i++) {        String name = names.get(i);        if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX)                && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) {            if (Constants.DEFAULT_KEY.equals(name)) {                if (!usrs.isEmpty()) {                    exts.addAll(0, usrs);                    usrs.clear();                }            } else {                T ext = getExtension(name);                usrs.add(ext);            }        }    }    if (!usrs.isEmpty()) {        exts.addAll(usrs);    }    return exts;}////https://www.jianshu.com/u/ee989c623747

https://blog.csdn.net/yuansha...
https://blog.csdn.net/qq_3521...