从ServiceConfig类的protocol属性开始看起:

private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
    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);          //初始化loader        if (loader == null) {            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);        }        return loader;    }

loader是通过new ExtensionLoader<T>(type)初始化的,进入new ExtensionLoader<Protocol.class>(type)构造方法:

    private ExtensionLoader(Class<?> type) { //将type赋值给全局变量type        this.type = type;        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());    }

因为此时type为Protocol.class,不等于ExtensionFactory.class,所以走的是ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()。

第二次进入getExtensionLoader办法,此时type为ExtensionFactory,初始化loader,进入new ExtensionLoader<ExtensionFactory.class>(type),type等于ExtensionFactory.class,那么objectFactory 赋值为null,构造方法执行结束,返回loader为 ExtensionLoader<ExtensionFactory.class>,戒指执行loader.getAdaptiveExtension()),即ExtensionLoader<ExtensionFactory.class>.getAdaptiveExtension()办法:

  @SuppressWarnings("unchecked")    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;    }    @SuppressWarnings("unchecked")    private T createAdaptiveExtension() {        try {            //先看getAdaptiveExtensionClass            return injectExtension((T) getAdaptiveExtensionClass().newInstance());        } catch (Exception e) {            throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);        }    }    private Class<?> getAdaptiveExtensionClass() {         //进入办法        getExtensionClasses();        if (cachedAdaptiveClass != null) {            return cachedAdaptiveClass;        }        return cachedAdaptiveClass = createAdaptiveExtensionClass();    }    private Map<String, Class<?>> getExtensionClasses() {        Map<String, Class<?>> classes = cachedClasses.get();        if (classes == null) {            synchronized (cachedClasses) {                classes = cachedClasses.get();                if (classes == null) {                    //进入load办法                    classes = loadExtensionClasses();                    cachedClasses.set(classes);                }            }        }        return classes;    }    // synchronized in getExtensionClasses    private Map<String, Class<?>> loadExtensionClasses() {        //若type有spi注解且有value,则将cachedDefaultName赋值为该value        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];            }        }        Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();        // 别离装载META-INF/resources目录下        // "META-INF/services/",        // "META-INF/dubbo/",        //"META-INF/dubbo/internal/"三个目录的合乎type的类        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);        loadDirectory(extensionClasses, DUBBO_DIRECTORY);        loadDirectory(extensionClasses, SERVICES_DIRECTORY);        return extensionClasses;    }

type即为上文的ExtensionFactory类.
比方META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory的内容如下:
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory

    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);        }    }    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) {                                //进入这里                                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);        }    }    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.");        }        //判断类上有没有Adaptive注解              if (clazz.isAnnotationPresent(Adaptive.class)) {            // 有的话则将cachedAdaptiveClass赋值为该类            //比方 AdaptiveExtensionFactory            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 if (isWrapperClass(clazz)) {            Set<Class<?>> wrappers = cachedWrapperClasses;            if (wrappers == null) {                cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();                wrappers = cachedWrapperClasses;            }            wrappers.add(clazz);        } else {            clazz.getConstructor();            //获取类简名,比方SpringExtensionFactory就是spring,AdaptiveExtensionFactory就是adaptive            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) {                //若类上有注解就放入map,AdaptiveExtensionFactory有注解,SpringExtensionFactory没有                //那么                Activate activate = clazz.getAnnotation(Activate.class);                if (activate != null) {                    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());                    }                }            }        }    }/**判断办法就是有没有type为参数的构造方法**/    private boolean isWrapperClass(Class<?> clazz) {        try {            clazz.getConstructor(type);            return true;        } catch (NoSuchMethodException e) {            return false;        }    }

下面的代码简略说就是扫描META-INF/services,META-INF/dubbo,META-INF/dubbo/internal下的文件,找到合乎type实现类放到map里。
再回到getAdaptiveExtensionClass办法,cachedAdaptiveClass对象在方才代码中被赋值为了
AdaptiveExtensionFactory,如果扫描过程中cachedAdaptiveClass没有被赋值,即没有实现类上有@Adaptive注解,那么就会执行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();        return compiler.compile(code, classLoader);    }@SPI("javassist")public interface Compiler {    /**     * Compile java source code.     *     * @param code        Java source code     * @param classLoader classloader     * @return Compiled class     */    Class<?> compile(String code, ClassLoader classLoader);}

通过同样的代码,找到了Compiler的实现类AdaptiveCompiler:

       @Override    public Class<?> compile(String code, ClassLoader classLoader) {        Compiler compiler;        ExtensionLoader<Compiler> loader = ExtensionLoader.getExtensionLoader(Compiler.class);        String name = DEFAULT_COMPILER; // copy reference        //DEFAULT_COMPILER为空        if (name != null && name.length() > 0) {            compiler = loader.getExtension(name);        } else {            //执行这里            compiler = loader.getDefaultExtension();        }        return compiler.compile(code, classLoader);    }    /**     * Return default extension, return <code>null</code> if it's not configured.     */    public T getDefaultExtension() {        getExtensionClasses();        if (null == cachedDefaultName || cachedDefaultName.length() == 0                || "true".equals(cachedDefaultName)) {            return null;        }        // 加载cachedDefaultName的类        return getExtension(cachedDefaultName);    }

下面的代码会将接口里@SPI注解指定的值赋给cachedDefaultName,此时就会装载此类作为接口默认类。

通过spi获取ExtensionLoader实现,回到createAdaptiveExtension办法:

    private T createAdaptiveExtension() {        try {          //getAdaptiveExtensionClass,通过spi实例化扩大类            //injectExtension管制反转            return injectExtension((T) getAdaptiveExtensionClass().newInstance());        } catch (Exception e) {            throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);        }    }    private T injectExtension(T instance) {        try {            // objectFactory在构造方法进行过赋值,为null,所以间接返回instance            if (objectFactory != null) {                for (Method method : instance.getClass().getMethods()) {                    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                         */                        // 过滤禁止主动注入的办法                        if (method.getAnnotation(DisableInject.class) != null) {                            continue;                        }                        Class<?> pt = method.getParameterTypes()[0];                        try {                            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) {                                method.invoke(instance, object);                            }                        } catch (Exception e) {                            logger.error("fail to inject via method " + method.getName()                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);                        }                    }                }            }        } catch (Exception e) {            logger.error(e.getMessage(), e);        }        return instance;    }

回到getAdaptiveExtension办法,instance创立结束吗,赋值给cachedAdaptiveInstance,
ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()办法执行结束,一句话概括就是通过spi拿到ExtensionFactory接口的实现类(AdaptiveExtensionFactory),并赋值给objectFactory。
至此,new ExtensionLoader<Protocol.class>(Protocol.class)办法执行结束,
再回到getExtensionLoader<Protocol.class>办法,将new ExtensionLoader<Protocol.class>(Protocol.class)对象赋值给loader,即ExtensionLoader.getExtensionLoader(Protocol.class)办法获取到了该loader,而后继续执行loader.getAdaptiveExtension()办法。

通过和下面一样的流程,始终到:

    private Class<?> getAdaptiveExtensionClass() {        //进入办法        getExtensionClasses();   //cachedAdaptiveClass为空,因为Protocol.class没有实现类有@Adaptive注解//所以接着执行createAdaptiveExtensionClass        if (cachedAdaptiveClass != null) {            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();        //生产代理类        return compiler.compile(code, classLoader);    }  /**     * 生产代理类代码string     * @return     */    private String createAdaptiveExtensionClassCode() {        StringBuilder codeBuilder = new StringBuilder();        Method[] methods = type.getMethods();        boolean hasAdaptiveAnnotation = false;        for (Method m : methods) {            if (m.isAnnotationPresent(Adaptive.class)) {                hasAdaptiveAnnotation = true;                break;            }        }        //实现类必须至多一个上有@Adaptive注解,否则不予代理        // 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!");        // 拼包名、类名        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(" {");        //遍历办法        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);            //没有@Adaptive注解的办法抛异样            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;                //办法参数必须要蕴含URL.class                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) {                    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()};                }                boolean hasInvocation = false;                //判断参数是否蕴含Invocation.class                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;                //依据注解value拼接url调用代码                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 ");                }                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();    }

createAdaptiveExtensionClassCode()办法就是拼接代理类代码的string,供后续javassist生产代理类。拿到complier的实现类AdaptiveCompiler后,开始生产代理类,compiler.compile(code, classLoader):

    @Override    public Class<?> compile(String code, ClassLoader classLoader) {        Compiler compiler;        ExtensionLoader<Compiler> loader = ExtensionLoader.getExtensionLoader(Compiler.class);        String name = DEFAULT_COMPILER; // copy reference        //DEFAULT_COMPILER为空        if (name != null && name.length() > 0) {            compiler = loader.getExtension(name);        } else {            //执行这里            compiler = loader.getDefaultExtension();        }        return compiler.compile(code, classLoader);    }    /**     * Return default extension, return <code>null</code> if it's not configured.     */    public T getDefaultExtension() {        getExtensionClasses();        if (null == cachedDefaultName || cachedDefaultName.length() == 0                || "true".equals(cachedDefaultName)) {            return null;        }        // 加载cachedDefaultName的类,即compiler接口上spi注解的value,JavassistCompiler        return getExtension(cachedDefaultName);    }

拿到JavassistCompiler后,进行compile:

    @Override    public Class<?> compile(String code, ClassLoader classLoader) {        code = code.trim();        Matcher matcher = PACKAGE_PATTERN.matcher(code);        String pkg;        if (matcher.find()) {            pkg = matcher.group(1);        } else {            pkg = "";        }        matcher = CLASS_PATTERN.matcher(code);        String cls;        if (matcher.find()) {            cls = matcher.group(1);        } else {            throw new IllegalArgumentException("No such class name in " + code);        }        String className = pkg != null && pkg.length() > 0 ? pkg + "." + cls : cls;        try {            //当类不存在时,办法会报错,就会执行catch里的doCompile办法,调用通过javassist进行生成类            return Class.forName(className, true, ClassHelper.getCallerClassLoader(getClass()));        } catch (ClassNotFoundException e) {            if (!code.endsWith("}")) {                throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");            }            try {                return doCompile(className, code);            } catch (RuntimeException t) {                throw t;            } catch (Throwable t) {                throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code: \n" + code + "\n, stack: " + ClassUtils.toString(t));            }        }    }

最初会通过javassist生成代理类com.alibaba.dubbo.rpc.Protocol$Adaptive,残缺代码如下:

package com.alibaba.dubbo.rpc;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class Protocol$Adaptive 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.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);}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);}}

对于javassist生成类的形式在此不再阐明,有趣味同学能够自行搜寻。
至此,Protocol类通过dubbo的spi生成了扩大类Protocol$Adaptive。