Dubbo源码—2.服务引用时创建代理的流程

76 阅读11分钟

大纲

1.Dubbo服务引用的主流程

2.服务引用时创建动态代理的流程

3.DynamicDirectory与Invoker的关系

4.基于Invoker来创建动态代理对象

5.动态代理生成后检查Invoker是否有效


1.Dubbo服务引用的主流程

ReferenceConfig的get()方法在进行服务引用时,首先也会初始化相关的组件,然后再创建并初始化服务的动态代理对象,最后返回服务的动态代理对象,其中会通过ReferenceConfig的createProxy()方法创建服务的动态代理对象。

public class Application {
    public static void main(String[] args) throws Exception {
        //Reference和ReferenceConfig是什么
        //Reference是一个引用,是对Provider端的一个服务实例的引用
        //ReferenceConfig这个服务实例的引用的一些配置
        //通过泛型传递了这个服务实例对外暴露的接口
        ReferenceConfig<DemoService> reference = new ReferenceConfig<>();

        //设置应用名称
        reference.setApplication(new ApplicationConfig("dubbo-demo-api-consumer"));

        //设置注册中心的地址,默认是ZooKeeper
        reference.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));

        //设置元数据上报地址
        reference.setMetadataReportConfig(new MetadataReportConfig("zookeeper://127.0.0.1:2181"));

        //设置要调用的服务的接口
        reference.setInterface(DemoService.class);

        //直接通过ReferenceConfig的get()方法来拿到一个DemoService接口
        //它是一个动态代理接口,只要被调用,便会通过底层调用Provider服务实例的对应接口
        DemoService service = reference.get();

        //下面调用动态代理的接口
        //会进入InvokerInvocationHandler的invoke()方法中
        String message = service.sayHello("dubbo");

        System.out.println(message);
        Thread.sleep(10000000L);
    }
}

public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
    //ref指向了服务的动态代理对象
    private transient volatile T ref;
    ...

    @Override
    public T get() {
        //检测当前ReferenceConfig的状态
        if (destroyed) {
            throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
        }

        //ref指向了服务的动态代理对象
        if (ref == null) {
            //1.执行相关组件的初始化
            //通过获取到的ModuleDeployer来对相关组件进行初始化
            //比如会对MetadataReport元数据上报组件进行构建和初始化,以及启动(建立跟zk的连接)
            getScopeModel().getDeployer().start();
            synchronized (this) {
                if (ref == null) {
                    //2.初始化服务的动态代理对象ref
                    init();
                }
            }
        }

        //3.返回服务的动态代理对象
        return ref;
    }

    protected synchronized void init() {
        ...
        //执行服务实例的刷新操作
        //也就是刷新ProviderConfig -> MethodConfig -> ArgumentConfig
        if (!this.isRefreshed()) {
            this.refresh();
        }

        //init serviceMetadata
        //对Metadata元数据进行初始化以及存储注册等一系列的操作
        //封装一个ConsumerModel,即把Consumer的数据封装起来放到对应的repository里
        initServiceMetadata(consumer);
        ...
        
        //调用ReferenceConfig的createProxy()方法创建服务的动态代理对象
        //这是构建整个代理的入口
        ref = createProxy(referenceParameters);

        //创建完动态代理后,把这个代理设置给serviceMetadata以及consumerModel
        serviceMetadata.setTarget(ref);
        serviceMetadata.addAttribute(PROXY_CLASS_REF, ref);

        consumerModel.setDestroyRunner(getDestroyRunner());
        consumerModel.setProxyObject(ref);
        consumerModel.initMethodModels();

        //检查一下Invoker是否可用
        checkInvokerAvailable();
    }
    ...
}

2.服务引用时创建动态代理的流程

ReferenceConfig的createProxy()方法创建动态代理创建时,首先会通过parseUrl()方法等方法进行地址处理,然后才通过createInvokerForRemote()方法创建动态代理。

而createInvokerForRemote()方法首先会通过RegistryProtocol的refer()方法构建出一个Invoker,然后再通过ProxyFactory适配器选择合适的ProxyFactory扩展实现,最后通过该ProxyFactory扩展实现 + 该Invoker创建出动态代理对象。

//-> ReferenceConfig.createProxy()
//-> ReferenceConfig.parseUrl() + ReferenceConfig.aggregateUrlFromRegistry()
//-> ReferenceConfig.createInvokerForRemote()
//-> Protocol$Adaptive.refer()
//-> ProtocolSerializationWrapper.refer()
//-> ProtocolFilterWrapper.refer()
//-> ProtocolListenerWrapper.refer()
//-> RegistryProtocol.refer() => invoker
//-> proxyFactory.getProxy(invoker, ProtocolUtils.isGeneric(generic))
//-> ProxyFactory$Adaptive.getProxy()
//-> StubProxyFactoryWrapper.getProxy()
//-> AbstractProxyFactory.getProxy()
//-> JavassistProxyFactory.getProxy()
//-> Proxy.getProxy()

public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
    //The invoker of the reference service
    private transient volatile Invoker<?> invoker;
    ...

    private T createProxy(Map<String, String> referenceParameters) {
        //Provider端有一个本地发布的动作,本地发布即把目标实现类封装成一个ProxyInvoker
        //然后再通过InjvmProtocol发布出去,也就是把ProxyInvoker封装成InjvmExporter
        //所以在同一个JVM里进行本地服务调用时,调用的便是本地发布出去的ProxyInvoker

        //根据url的协议、scope以及injvm等参数检测是否需要本地引用
        if (shouldJvmRefer(referenceParameters)) {
            createInvokerForLocal(referenceParameters);
        } else {
            urls.clear();
            meshModeHandleUrl(referenceParameters);
            if (StringUtils.isNotEmpty(url)) {
                //user specified URL, could be peer-to-peer address, or register center's address.
                //解析用户指定的URL,可能是一个点对点的调用地址,或者是一个注册中心的地址
                parseUrl(referenceParameters);
            } else {
                //if protocols not in jvm checkRegistry
                if (!LOCAL_PROTOCOL.equalsIgnoreCase(getProtocol())) {
                    //加载注册中心的地址RegistryURL
                    aggregateUrlFromRegistry(referenceParameters);
                }
            }
            //接下来是核心源码的第一步:
            //通过RegistryProtocol创建invoker
            createInvokerForRemote();
        }
        ...

        //这些都是url的处理
        URL consumerUrl = new ServiceConfigURL(CONSUMER_PROTOCOL, referenceParameters.get(REGISTER_IP_KEY), 0, referenceParameters.get(INTERFACE_KEY), referenceParameters);
        consumerUrl = consumerUrl.setScopeModel(getScopeModel());
        consumerUrl = consumerUrl.setServiceModel(consumerModel);
        //对于Consumer的元数据,会通过如下代码在这里进行发布
        MetadataUtils.publishServiceDefinition(consumerUrl, consumerModel.getServiceModel(), getApplicationModel());

        //create service proxy
        //通过ProxyFactory适配器选择合适的ProxyFactory扩展实现,基于invoker对象创建动态代理对象
        return (T) proxyFactory.getProxy(invoker, ProtocolUtils.isGeneric(generic));
    }
    ...

    private void createInvokerForRemote() {
        //createInvokerForRemote()方法的核心就两个步骤:
        //第一是执行RegistryProtocol.refer()构建出一个invoker;
        //第二是执行Cluster.getCluster().join() + new StaticDirectory()对invokers进行加工处理,最后覆盖到invoker上;
        //protocolSPI.refer -> invokers -> new StaticDirectory() -> cluster.join -> invoker
        if (urls.size() == 1) {
            //注册中心单Provider或直连单个服务提供方时,通过Protocol的适配器选择对应的Protocol实现创建Invoker对象
            //也就是会基于RegistryProtocol.refer构建出一个Invoker
            //比如dubbo-demo-api下的示例会构建出一个MigrationInvoker,且curUrl不是注册中心的
            //而且该MigrationInvoker的构成是:
            //其registry属性为装饰ZookeeperRegistry的ListenerRegistryWrapper
            //其cluster属性为装饰FailoverCluster的MockCLusterWrapper
            URL curUrl = urls.get(0);

            //调用Protocol$Adaptive的refer()方法
            invoker = protocolSPI.refer(interfaceClass, curUrl);

            //registry url, mesh-enable and unloadClusterRelated is true, not need Cluster.
            if (!UrlUtils.isRegistry(curUrl) && !curUrl.getParameter(UNLOAD_CLUSTER_RELATED, false)) {
                List<Invoker<?>> invokers = new ArrayList<>();
                invokers.add(invoker);
                //对Invoker进行深加工和处理后又拿到了一个Invoker,覆盖原invoker
                invoker = Cluster.getCluster(scopeModel, Cluster.DEFAULT).join(new StaticDirectory(curUrl, invokers), true);
            }
        } else {
            //注册中心多Provider或直连多个服务提供方时,根据每个URL创建Invoker对象
            List<Invoker<?>> invokers = new ArrayList<>();
            URL registryUrl = null;
            for (URL url : urls) {
                //For multi-registry scenarios, it is not checked whether each referInvoker is available.
                //Because this invoker may become available later.
                invokers.add(protocolSPI.refer(interfaceClass, url));

                if (UrlUtils.isRegistry(url)) {
                    //use last registry url
                    //确定是多注册中心,还是直连多个Provider
                    registryUrl = url;
                }
            }

            if (registryUrl != null) {
                //在依赖注册中心的场景中,则使用ZoneAwareCluster作为Cluster的默认实现,生成对应的Invoker对象
                //registry url is available
                //for multi-subscription scenario, use 'zone-aware' policy by default
                String cluster = registryUrl.getParameter(CLUSTER_KEY, ZoneAwareCluster.NAME);
                //The invoker wrap sequence would be: ZoneAwareClusterInvoker(StaticDirectory) -> FailoverClusterInvoker
                //(RegistryDirectory, routing happens here) -> Invoker
                invoker = Cluster.getCluster(registryUrl.getScopeModel(), cluster, false).join(new StaticDirectory(registryUrl, invokers), false);
            } else {
                //在直连Provider的场景中,则使用Cluster适配器选择合适的扩展实现
                //not a registry url, must be direct invoke.
                if (CollectionUtils.isEmpty(invokers)) {
                    throw new IllegalArgumentException("invokers == null");
                }
                URL curUrl = invokers.get(0).getUrl();
                String cluster = curUrl.getParameter(CLUSTER_KEY, Cluster.DEFAULT);
                invoker = Cluster.getCluster(scopeModel, cluster).join(new StaticDirectory(curUrl, invokers), true);
            }
        }
    }
    ...
}

@SPI(value = "dubbo", scope = ExtensionScope.FRAMEWORK)
public interface Protocol {
    //默认端口
    int getDefaultPort();

    //Protocol接收到一个请求之后,必须要记录请求的源地址
    //对同一个服务实例(url)发布一次和发布多次,是没有任何区别的
    //export()方法会将一个Invoker发布出去
    //export()方法的实现需要是幂等的,即同一个服务暴露多次和暴露一次的效果是相同的
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

    //Protocol必须根据一个url和接口类型,获取到对应的Invoker
    //refer()方法会引用一个Invoker
    //refer()方法会根据参数返回一个Invoker对象,Consumer端可以通过这个Invoker请求到Provider端的服务
    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

    //销毁export()方法以及refer()方法使用到的Invoker对象,释放当前Protocol对象底层占用的资源
    void destroy();

    //返回当前Protocol底层的全部ProtocolServer
    default List<ProtocolServer> getServers() {
        return Collections.emptyList();
    }
}

@SPI(value = "javassist", scope = FRAMEWORK)
public interface ProxyFactory {
    //为传入的Invoker对象创建代理对象
    @Adaptive({PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;

    //为传入的Invoker对象创建代理对象
    @Adaptive({PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;

    //将传入的代理对象封装成Invoker对象
    @Adaptive({PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}
//-> Protocol$Adaptive.refer()
//-> ProtocolSerializationWrapper.refer()
//-> ProtocolFilterWrapper.refer()
//-> ProtocolListenerWrapper.refer()
//-> RegistryProtocol.refer() => invoker

public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
    public int getDefaultPort()  {
        throw new UnsupportedOperationException("The method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
    }

    public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException {
        if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
        if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
        org.apache.dubbo.common.URL url = arg0.getUrl();
        String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
        if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
        ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.Protocol.class);
        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
        return extension.export(arg0);
    }

    public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException {
        if (arg1 == null) throw new IllegalArgumentException("url == null");
        org.apache.dubbo.common.URL url = arg1;
        String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
        if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
        ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.Protocol.class);
        org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
        return extension.refer(arg0, arg1);
    }

    public void destroy()  {
        throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
    }

    public java.util.List getServers()  {
        throw new UnsupportedOperationException("The method public default java.util.List org.apache.dubbo.rpc.Protocol.getServers() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
    }
}

@Activate
public class ProtocolSerializationWrapper implements Protocol {
    private Protocol protocol;

    public ProtocolSerializationWrapper(Protocol protocol) {
        this.protocol = protocol;
    }

    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        getFrameworkModel(invoker.getUrl().getScopeModel()).getServiceRepository().registerProviderUrl(invoker.getUrl());
        //下面会调用ProtocolFilterWrapper.export()方法
        return protocol.export(invoker);
    }

    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        //下面会调用ProtocolFilterWrapper.refer()方法
        return protocol.refer(type, url);
    }
    ...
}

@Activate(order = 100)
public class ProtocolFilterWrapper implements Protocol {
    private final Protocol protocol;

    public ProtocolFilterWrapper(Protocol protocol) {
        if (protocol == null) {
            throw new IllegalArgumentException("protocol == null");
        }
        this.protocol = protocol;
    }

    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        if (UrlUtils.isRegistry(invoker.getUrl())) {
            return protocol.export(invoker);
        }
        FilterChainBuilder builder = getFilterChainBuilder(invoker.getUrl());
        //下面会调用ProtocolListenerWrapper.export()方法
        return protocol.export(builder.buildInvokerChain(invoker, SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
    }

    private <T> FilterChainBuilder getFilterChainBuilder(URL url) {
        return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel()).getDefaultExtension();
    }

    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        if (UrlUtils.isRegistry(url)) {
            //下面会调用ProtocolListenerWrapper.refer()方法
            return protocol.refer(type, url);
        }
        FilterChainBuilder builder = getFilterChainBuilder(url);
        return builder.buildInvokerChain(protocol.refer(type, url), REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
    }
    ...
}

@Activate(order = 200)
public class ProtocolListenerWrapper implements Protocol {
    private final Protocol protocol;

    public ProtocolListenerWrapper(Protocol protocol) {
        if (protocol == null) {
            throw new IllegalArgumentException("protocol == null");
        }
        this.protocol = protocol;
    }

    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        if (UrlUtils.isRegistry(invoker.getUrl())) {
            return protocol.export(invoker);
        }
        //下面会调用DubboProtocol.export()方法
        return new ListenerExporterWrapper<T>(protocol.export(invoker), Collections.unmodifiableList(
            ScopeModelUtil.getExtensionLoader(ExporterListener.class, invoker.getUrl().getScopeModel()).getActivateExtension(invoker.getUrl(), EXPORTER_LISTENER_KEY))
        );
    }

    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        if (UrlUtils.isRegistry(url)) {
            //下面会调用RegistryProtocol.refer()方法
            return protocol.refer(type, url);
        }
        Invoker<T> invoker = protocol.refer(type, url);
        if (StringUtils.isEmpty(url.getParameter(REGISTRY_CLUSTER_TYPE_KEY))) {
            invoker = new ListenerInvokerWrapper<>(invoker, Collections.unmodifiableList(
                ScopeModelUtil.getExtensionLoader(InvokerListener.class, invoker.getUrl().getScopeModel()).getActivateExtension(url, INVOKER_LISTENER_KEY)
            ));
        }
        return invoker;
    }
    ...
}
//-> ProxyFactory$Adaptive.getProxy()
//-> StubProxyFactoryWrapper.getProxy()
//-> AbstractProxyFactory.getProxy()
//-> JavassistProxyFactory.getProxy()
//-> Proxy.getProxy

public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory {
    ...
    public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0, boolean arg1) throws org.apache.dubbo.rpc.RpcException {
        if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
        if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
        org.apache.dubbo.common.URL url = arg0.getUrl();
        String extName = url.getParameter("proxy", "javassist");
        if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])");
        ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.ProxyFactory.class);
        org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName);
        return extension.getProxy(arg0, arg1);
    }
    ...
}

public class StubProxyFactoryWrapper implements ProxyFactory {
    //包含一个JavassistProxyFactory
    private final ProxyFactory proxyFactory;
    private Protocol protocol;

    public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
        this.proxyFactory = proxyFactory;
    }

    public void setProtocol(Protocol protocol) {
        this.protocol = protocol;
    }

    @Override
    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
        //为什么它的名字叫stub打桩?
        //stub这个名字一般代表的是远程网络访问的动态代理
        //通过这个stub可以对远程的机器进行网络访问
        //stub打桩思想,是在网络远程访问里经常会使用的一种方法,类似于电线杆打桩一样
        //比如机器A和机器B之间进行的远程网络访问,必然要通过网络来进行连接和访问
        //机器A在进行远程RPC访问时,其调用代码,最好不要直接写网络通信的逻辑,而是写针对某个接口类型对象的方法调用
        //这样在机器A上面进行RPC调用时就像是在本地调用一样,都是直接调用某个对象的方法
        //然后在这个对象的方法里,再去写网络通信的逻辑和目标机器B进行网络连接,并发送调用请求
        //所以在机器A上会针对调用的那个接口,来动态去生成一个实现了该接口的类,也就是动态代理的代理类或者是stub打桩
        //类似于在机器A上打下的一个伪装成目标类的桩,然后针对打的这个stub桩去进行调用,stub内部会编写网络通信代码实现跨机器的访问
        //这就是远程网络连接和通信的stub打桩思想
        //下面使用了抽象代理工厂来获取真正的动态代理
        //下面会调用JavassistProxyFactory的getProxy()方法
        //也就是调用AbstractProxyFactory的getProxy()方法
        T proxy = proxyFactory.getProxy(invoker, generic);
        ...

        return proxy;
    }
    ...
}

public abstract class AbstractProxyFactory implements ProxyFactory {
    ...
    @Override
    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
        //记录要代理的接口
        LinkedHashSet<Class<?>> interfaces = new LinkedHashSet<>();
        ClassLoader classLoader = getClassLoader(invoker);

        //获取URL中interfaces参数指定的接口
        String config = invoker.getUrl().getParameter(INTERFACES);
        if (StringUtils.isNotEmpty(config)) {
            //按照逗号切分interfaces参数,得到接口集合,然后进行遍历
            String[] types = COMMA_SPLIT_PATTERN.split(config);
            //遍历接口集合,并记录这些接口信息
            for (String type : types) {
                //对每个接口都拿出对应的class对象,放到interfaces集合里
                interfaces.add(ReflectUtils.forName(classLoader, type));
            }
        }
        ...

        //获取Invoker中type字段指定的接口
        interfaces.add(invoker.getInterface());

        //添加EchoService、Destroyable两个默认接口
        interfaces.addAll(Arrays.asList(INTERNAL_INTERFACES));

        //调用抽象的getProxy()重载方法
        //Dubbo的动态代理技术有如下两种:
        //一.javassist(动态拼接类的代码字符串,通过动态编译来动态生成一个类)
        //二.jdk(通过jdk提供的API利用反射来生成动态代理)
        //默认下面会调用子类JavassistProxyFactory的getProxy()方法
        return getProxy(invoker, interfaces.toArray(new Class<?>[0]));
    }

    public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types);
    ...
}

public class JavassistProxyFactory extends AbstractProxyFactory {
    private final static Logger logger = LoggerFactory.getLogger(JavassistProxyFactory.class);
    private final JdkProxyFactory jdkProxyFactory = new JdkProxyFactory();

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        try {
            //下面的Proxy是Dubbo自己实现的Proxy
            return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
        } catch (Throwable fromJavassist) {
            //try fall back to JDK proxy factory
            try {
                T proxy = jdkProxyFactory.getProxy(invoker, interfaces);
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy success. " + "Interfaces: " + Arrays.toString(interfaces), fromJavassist);
                return proxy;
            } catch (Throwable fromJdk) {
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + "Interfaces: " + Arrays.toString(interfaces) + " Javassist Error.", fromJavassist);
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + "Interfaces: " + Arrays.toString(interfaces) + " JDK Error.", fromJdk);
                throw fromJavassist;
            }
        }
    }
    ...
}

public class Proxy {
    private static final Map<ClassLoader, Map<String, Proxy>> PROXY_CACHE_MAP = new WeakHashMap<>();
    ...

    public static Proxy getProxy(Class<?>... ics) {
        //ClassLoader from App Interface should support load some class from Dubbo
        ClassLoader cl = ics[0].getClassLoader();
        ProtectionDomain domain = ics[0].getProtectionDomain();

        //use interface class name list as key.
        //生成的动态代理类主要实现了如下三个接口:
        //org.apache.dubbo.demo.DemoService
        //org.apache.dubbo.rpc.service.EchoService
        //org.apache.dubbo.rpc.service.Destoryable
        String key = buildInterfacesKey(cl, ics);

        //get cache by class loader.
        final Map<String, Proxy> cache;
        synchronized (PROXY_CACHE_MAP) {
            cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new ConcurrentHashMap<>());
        }

        //接口列表将会作为第二层集合的Key
        Proxy proxy = cache.get(key);
        if (proxy == null) {
            synchronized (ics[0]) {
                proxy = cache.get(key);
                if (proxy == null) {
                    //create Proxy class.
                    proxy = new Proxy(buildProxyClass(cl, ics, domain));
                    cache.put(key, proxy);
                }
            }
        }
        return proxy;
    }
    ...
}

在RegistryProtocol的refer()的方法中,首先会获取一个包含zk注册中心ZooKeeperRegistry的ListenerRegistryWrapper,然后再获取一个包含故障转移集群FailoverCluster的MockClusterWrapper。

//-> RegistryProtocol.refer()
//-> getRegistry() => ZooKeeperRegistry
//-> Cluster.getCluster() => MockClusterWrapper、FailoverCluster
//-> RegistryProtocol.doRefer()
//-> RegistryProtocol.getMigrationInvoker()
//-> RegistryProtocol.interceptInvoker()
//-> MigrationRuleListener.onRefer()
//-> MigrationRuleHandler.doMigrate()
//-> MigrationRuleHandler.refreshInvoker()
//-> MigrationInvoker.refreshInterfaceInvoker() + MigrationInvoker.refreshServiceDiscoveryInvoker()
//-> InterfaceCompatibleRegistryProtocol.getInvoker() + RegistryProtocol.getServiceDiscoveryInvoker()
//-> RegistryProtocol.doCreateInvoker()

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //下面会返回一个MigrationInvoker,其构成是:
    //registry属性为装饰ZookeeperRegistry的ListenerRegistryWrapper
    //cluster属性为装饰FailoverCluster的MockCLusterWrapper
    //invoker和serviceDiscoveryInvoker属性都为MockClusterInvoker
    //其中前者的directory属性=注入了ZookeeperRegistry的RegistryDirectory
    //后者的directory属性=注入了ServiceDiscoveryRegistry的ServiceDiscoveryRegistryDirectory
    //但两者的invoker属性都是AbstractCluster的内部类ClusterFilterInvoker
    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        //从URL中获取注册中心的URL
        url = getRegistryUrl(url);

        //获取Registry实例,这里的RegistryFactory对象是通过Dubbo SPI的自动装载机制注入的
        //1.先拿到一个ListenerRegistryWrapper,里面包含一个zk注册中心ZooKeeperRegistry
        Registry registry = getRegistry(url);
        if (RegistryService.class.equals(type)) {
            return proxyFactory.getInvoker((T) registry, type, url);
        }

        //group="a,b" or group="*"
        //从注册中心URL的refer参数中获取此次服务引用的一些参数,其中就包括group
        Map<String, String> qs = (Map<String, String>) url.getAttribute(REFER_KEY);
        String group = qs.get(GROUP_KEY);
        if (StringUtils.isNotEmpty(group)) {
            if ((COMMA_SPLIT_PATTERN.split(group)).length > 1 || "*".equals(group)) {
                //如果此次可以引用多个group的服务,则Cluser实现使用MergeableCluster实现
                //这里的getMergeableCluster()方法就会通过Dubbo SPI方式找到MergeableCluster实例
                return doRefer(Cluster.getCluster(url.getScopeModel(), MergeableCluster.NAME), registry, type, url, qs);
            }
        }

        //2.接着会拿到一个MockClusterWrapper,里面会包含一个故障转移集群FailoverCluster
        //Cluster是和集群容错强相关的
        //不同的Cluster会对应不同的Cluster Invoker
        //不同的Cluster Invoker就有调用失败时不同的集群容错策略和算法
        Cluster cluster = Cluster.getCluster(url.getScopeModel(), qs.get(CLUSTER_KEY));

        //doRefer()这种代码的编写技巧在很多框架系统都会使用
        //refer()方法会先做一些提前的准备工作,而正式的工作可以在方法名称的前面加一个do变成doRefer()方法来执行真正的工作
        //下面的doRefer()方法,执行时发现如果没有group参数或是group参数,则通过Cluster适配器选择Cluster实现
        return doRefer(cluster, registry, type, url, qs);
    }

    protected Registry getRegistry(final URL registryUrl) {
        //通过SPI自适应机制,去拿到对应的extension实例
        //这里的registryFactory为RegistryFactory$Adaptive
        RegistryFactory registryFactory = ScopeModelUtil.getExtensionLoader(RegistryFactory.class, registryUrl.getScopeModel()).getAdaptiveExtension();

        //调用RegistryFactory$Adaptive的getRegistry()方法
        //返回一个装饰ZookeeperRegistry的ListenerRegistryWrapper
        return registryFactory.getRegistry(registryUrl);
    }
    ...
}

@SPI(Cluster.DEFAULT)
public interface Cluster {
    String DEFAULT = "failover";

    //Merge the directory invokers to a virtual invoker.
    @Adaptive
    <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException;
    static Cluster getCluster(ScopeModel scopeModel, String name) {
        return getCluster(scopeModel, name, true);
    }

    static Cluster getCluster(ScopeModel scopeModel, String name, boolean wrap) {
        if (StringUtils.isEmpty(name)) {
            //name的默认值是failover
            name = Cluster.DEFAULT;
        }

        //比如RegistryProtocol.refer()方法的"Cluster.getCluster(url.getScopeModel(), qs.get(CLUSTER_KEY))"代码
        //就会获取到一个装饰着FailoverCluster的MockClusterWrapper
        return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
    }
}

public class MockClusterWrapper implements Cluster {
    //包含一个故障转移集群FailoverCluster
    private final Cluster cluster;

    public MockClusterWrapper(Cluster cluster) {
        //Wrapper类都会有一个拷贝构造函数,装饰器模式
        this.cluster = cluster;
    }
    ...
}

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //doRefer()方法传入的参数cluster就是装饰着FailoverCluster的MockClusterWrapper
    //传入的参数registry为装饰ZookeeperRegistry的ListenerRegistryWrapper
    //这里会把组装好的Invoker体系里的最源头的一个Invoker进行返回,下一步就会去创建接口的动态代理并把该Invoker放进去
    //这样动态代理的方法被调用时,就可以通过该Invoker及其关联的Invoker来完成一个完整的RPC调用过程
    protected <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url, Map<String, String> parameters) {
        Map<String, Object> consumerAttribute = new HashMap<>(url.getAttributes());
        consumerAttribute.remove(REFER_KEY);
        String p = isEmpty(parameters.get(PROTOCOL_KEY)) ? CONSUMER : parameters.get(PROTOCOL_KEY);
        URL consumerUrl = new ServiceConfigURL(p, null, null, parameters.get(REGISTER_IP_KEY), 0, getPath(parameters, type), parameters, consumerAttribute);
        url = url.putAttribute(CONSUMER_URL_KEY, consumerUrl);

        //下面会以MigrationInvoker作为一个起点去构建一个Invoker链条;
        //这使用了经典的责任链模式,一环扣一环,先执行一个步骤再下一个步骤,把RPC调用的过程,一步步执行完毕;
        //但是在代码层面,却并非是严格的责任链模式来编码的,只是用到了这种责任链思想而已;
        //所以在这里会把不同的步骤和环节,拆分成不同的Invoker,把每个环节的代码逻辑内聚在单个Invoker内部;
        //再通过一系列的代码逻辑,把不同的环节的Invoker串联在一起,一个个按照顺序去串联;
        //这样真正执行时,就可以以MigrationInvoker作为一个起点,它会一个个的执行下一个Invoker;

        //下面这行代码可以理解为开始构建Invoker体系链条,也就是把源头Invoker给先准备好
        //传入的参数cluster就是装饰着FailoverCluster的MockClusterWrapper
        //getMigrationInvoker()所返回的MigrationInvoker中,它的invoker和serviceDiscoveryInvoker属性此时还是null
        ClusterInvoker<T> migrationInvoker = getMigrationInvoker(this, cluster, registry, type, url, consumerUrl);

        //接着下一步,要去继续组装后续的Invoker,然后把后续的Invoker构建好时,便设置给其上层Invoker;
        //所以在interceptInvoker()方法中,RegistryProtocol有责任在此把Invoker链条组装好;
        //但interceptInvoker字面上的意思就是拦截Invoker,字面上并不像是把后续的Invoker构建好设置给上层,有语义不清晰的嫌疑;

        //Invoker链条代表了RPC调用链路的全过程,每个步骤代表了一个环节,比如RPC调用过程里包含了如下环节:
        //migration(会有两个源头Invoker可以进行互相切换) -> mock降级 -> filter链条 -> 集群容错cluster -> 负载均衡 -> DubboInvoker
        //Dubbo应该针对每个环节进行对应的Invoker构建,并在每个环节的Invoker被构建好后,注入到上层的Invoker,从而完成Invoker链条的构建
        return interceptInvoker(migrationInvoker, url, consumerUrl);
    }

    protected <T> ClusterInvoker<T> getMigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        //构建基于服务发现机制迁移的Invoker
        //传入的cluster就是装饰着FailoverCluster的MockClusterWrapper
        //传入的registry为装饰ZookeeperRegistry的ListenerRegistryWrapper
        return new ServiceDiscoveryMigrationInvoker<T>(registryProtocol, cluster, registry, type, url, consumerUrl);
    }
    ...
}

public class ServiceDiscoveryMigrationInvoker<T> extends MigrationInvoker<T> {
    public ServiceDiscoveryMigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        super(registryProtocol, cluster, registry, type, url, consumerUrl);
    }
    ...
}

public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
    //服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> invoker;

    //这是一个名为serviceDiscoveryInvoker的ClusterInvoker实现类的实例,也是一个MockClusterInvoker
    private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
    private RegistryProtocol registryProtocol;

    //服务引用时,它是一个故障转移的集群FailoverCluster
    private Cluster cluster;

    //服务引用时,它是一个服务注册中心ZooKeeperRegistry
    ...
    
    public MigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        this(null, null, registryProtocol, cluster, registry, type, url, consumerUrl);
    }

    public MigrationInvoker(ClusterInvoker<T> invoker, ClusterInvoker<T> serviceDiscoveryInvoker, RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        //一开始创建MigrationInvoker时invoker属性是null
        //经过MigrationRuleListener.onRefer()方法的刷新后
        //也就是执行RegistryProtocol.doCreateInvoker()方法后
        //就会变为封装了DynamicDirectory和FailoverClusterInvoker的MockClusterInvoker
        this.invoker = invoker;

        //一开始创建MigrationInvoker时serviceDiscoveryInvoker属性是null
        //经过MigrationRuleListener.onRefer()方法的刷新后
        //也就是执行RegistryProtocol.doCreateInvoker()方法后
        //就会变为封装了DynamicDirectory和FailoverClusterInvoker的MockClusterInvoker
        this.serviceDiscoveryInvoker = serviceDiscoveryInvoker;
        this.registryProtocol = registryProtocol;

        //cluster就是装饰着FailoverCluster的MockClusterWrapper
        this.cluster = cluster;

        //registry是装饰着ZookeeperRegistry的ListenerRegistryWrapper
        this.registry = registry;
        ...
    }
    ...
}

public class MockClusterInvoker<T> implements ClusterInvoker<T> {
    private final Directory<T> directory;
    private final Invoker<T> invoker;

    public MockClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
        //传入的directory为DynamicDirectory
        //当初始化MigrationInvoker.invoker时,传入的directory为RegistryDirectory
        //当初始化MigrationInvoker.serviceDiscoveryInvoker时,传入的directory为ServiceDiscoveryRegistryDirectory
        //不管是RegistryDirectory,还是ServiceDiscoveryRegistryDirectory,其实都是DynamicDirectory
        this.directory = directory;

        //传入的invoker为AbstractCluster的内部类ClusterFilterInvoker
        //其filterInvoker属性的originalInvoker属性便为封装了DynamicDirectory的FailoverClusterInvoker
        this.invoker = invoker;
    }
    ...
}

RegistryProtocol的interceptInvoker()方法会加载相应的监听器实现,其中就包括了MigrationRuleListener。

MigrationRuleListener的onRefer()方法又会调用MigrationRuleHandler的doMigrate()方法。

MigrationRuleHandler的doMigrate()方法会调用MigrationRuleHandler的refreshInvoker()方法。

MigrationRuleHandler的refreshInvoker()方法会调用MigrationInvoker的refreshInterfaceInvoker()和refreshServiceDiscoveryInvoker()两个方法。MigrationInvoker的这两个方法又会调用RegistryProtocol的getInvoker()和getServiceDiscoveryInvoker()两个方法,也就是通过RegistryProtocol的doCreateInvoker()方法来刷新MigrationInvoker的invoker属性和serviceDiscoveryInvoker属性。

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //这里首先会取出RegistryProtocol里的监听回调器
    //然后遍历监听回调器进行回调处理
    protected <T> Invoker<T> interceptInvoker(ClusterInvoker<T> invoker, URL url, URL consumerUrl) {
        //根据URL中的registry.protocol.listener参数加载相应的监听器实现
        //也就是RegistryProtocol里的监听回调器
        List<RegistryProtocolListener> listeners = findRegistryProtocolListeners(url);
        if (CollectionUtils.isEmpty(listeners)) {
            return invoker;
        }

        //此时传入的invoker也就是MigrationInvoker中
        //它的invoker和serviceDiscoveryInvoker属性此时还是null
        for (RegistryProtocolListener listener : listeners) {
            //传递给监听器,比如下面会调用MigrationRuleListener.onRefer()方法
            //事实上默认下listeners只有MigrationRuleListener一个元素
            listener.onRefer(this, invoker, consumerUrl, url);
        }

        //此时传入的invoker也就是MigrationInvoker中
        //它的invoker和serviceDiscoveryInvoker属性就都为MockClusterInvoker
        //其中前者的directory属性=RegistryDirectory
        //后者的directory属性=ServiceDiscoveryRegistryDirectory
        //但两者的invoker属性都是AbstractCluster的内部类ClusterFilterInvoker
        return invoker;
    }

    protected List<RegistryProtocolListener> findRegistryProtocolListeners(URL url) {
        //通过SPI的Activate自动激活机制,针对指定的接口去获取符合的所有实现类
        return ScopeModelUtil.getExtensionLoader(RegistryProtocolListener.class, url.getScopeModel())
            .getActivateExtension(url, REGISTRY_PROTOCOL_LISTENER_KEY);
    }
    ...
}

@Activate
public class MigrationRuleListener implements RegistryProtocolListener, ConfigurationListener {
    //默认的迁移规则
    private volatile MigrationRule rule;
    ...
    
    @Override
    public void onRefer(RegistryProtocol registryProtocol, ClusterInvoker<?> invoker, URL consumerUrl, URL registryURL) {
        MigrationRuleHandler<?> migrationRuleHandler = handlers.computeIfAbsent((MigrationInvoker<?>) invoker, _key -> {
            //给这个MigrationInvoker设置一个MigrationRuleListener,也就是当前的这个listener
            //此外还构建一个MigrationRuleHandler
            ((MigrationInvoker<?>) invoker).setMigrationRuleListener(this);
            return new MigrationRuleHandler<>((MigrationInvoker<?>) invoker, consumerUrl);
        });

        //然后拿默认构建好的迁移规则处理器,来执行对应的迁移逻辑:
        //rule=INIT规则,比如下面会调用MigrationRuleHandler.doMigrate()
        migrationRuleHandler.doMigrate(rule);
    }
    ...
}

public class MigrationRuleHandler<T> {
    ...
    public synchronized void doMigrate(MigrationRule rule) {
        ...
        if (refreshInvoker(step, threshold, rule)) {
            setMigrationRule(rule);
        }
    }

    private boolean refreshInvoker(MigrationStep step, Float threshold, MigrationRule newRule) {
        ...
        switch (step) {
            case APPLICATION_FIRST:
                //比如会调用MigrationInvoker.migrateToApplicationFirstInvoker()
                migrationInvoker.migrateToApplicationFirstInvoker(newRule);
                break;
            case FORCE_APPLICATION:
                //比如会调用MigrationInvoker.refreshServiceDiscoveryInvoker()
                success = migrationInvoker.migrateToForceApplicationInvoker(newRule);
                break;
            case FORCE_INTERFACE:
            default:
                //比如会调用MigrationInvoker.refreshInterfaceInvoker()
                success = migrationInvoker.migrateToForceInterfaceInvoker(newRule);
        }
        ...
    }
    ...
}

public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
    //服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> invoker;

    //这是一个名为serviceDiscoveryInvoker的ClusterInvoker实现类的实例,也是一个MockClusterInvoker
    private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
    ...

    @Override
    public void migrateToApplicationFirstInvoker(MigrationRule newRule) {
        CountDownLatch latch = new CountDownLatch(0);

        //这里是比较关键的:
        //migration迁移有两个核心的Invoker: InterfaceInvoker,ServiceDiscoveryInvoker;
        //下面会进行Invoker的刷新处理,就是在给我们的MigrationInvoker去注入下一环节的Invoker
        refreshInterfaceInvoker(latch);//第一个InterfaceInvoker
        refreshServiceDiscoveryInvoker(latch);//第二个ServiceDiscoveryInvoker

        //directly calculate preferred invoker, will not wait until address notify
        //calculation will re-occurred when address notify later
        //下面会把MigrationRule传递进去;
        //也就是当两个Invoker刷新好后,会根据最新的迁移规则来决定当前应该用哪个Invoker来作为MigrationInvoker的下一级Invoker;
        calcPreferredInvoker(newRule);
    }

    protected void refreshInterfaceInvoker(CountDownLatch latch) {
        ...
        //这里是核心逻辑
        //入参cluster是装饰着FailoverCluster的MockClusterWrapper
        //入参registry是装饰着ZookeeperRegistry的ListenerRegistryWrapper
        //下面会调用InterfaceCompatibleRegistryProtocol的getInvoker()方法
        //这个invoker其实最后发现就是FailoverClusterInvoker
        invoker = registryProtocol.getInvoker(cluster, registry, type, url);
        ...
    }

    protected void refreshServiceDiscoveryInvoker(CountDownLatch latch) {
        ...
        //比如下面会调用RegistryProtocol子类InterfaceCompatibleRegistryProtocol的getServiceDiscoveryInvoker()方法
        serviceDiscoveryInvoker = registryProtocol.getServiceDiscoveryInvoker(cluster, registry, type, url);
        ...
    }
    ...
}

public class InterfaceCompatibleRegistryProtocol extends RegistryProtocol {
    ...
    @Override
    public <T> ClusterInvoker<T> getInvoker(Cluster cluster, Registry registry, Class<T> type, URL url) {
        //这里传入的registry是ZookeeperRegistry
        DynamicDirectory<T> directory = new RegistryDirectory<>(type, url);

        //下面会调用RegistryProtocol的doCreateInvoker()方法
        return doCreateInvoker(directory, cluster, registry, type);
    }

    @Override
    public <T> ClusterInvoker<T> getServiceDiscoveryInvoker(Cluster cluster, Registry registry, Class<T> type, URL url) {
        //这个getRegistry()会获取到装饰着ServiceDiscoveryRegistry的ListenerRegistryWrapper,对传入的registry进行覆盖
        registry = getRegistry(super.getRegistryUrl(url));
        DynamicDirectory<T> directory = new ServiceDiscoveryRegistryDirectory<>(type, url);

        //下面会调用RegistryProtocol的doCreateInvoker()方法
        return doCreateInvoker(directory, cluster, registry, type);
    }
    ...
}

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //入参directory是继承了DynamicDirectory的RegistryDirectory或者是继承了DynamicDirectory的ServiceDiscoveryRegistryDirectory
    //入参cluster是装饰着FailoverCluster的MockClusterWrapper
    protected <T> ClusterInvoker<T> doCreateInvoker(DynamicDirectory<T> directory, Cluster cluster, Registry registry, Class<T> type) {
        //设置注册中心
        directory.setRegistry(registry);
        //设置protocol协议
        directory.setProtocol(protocol);
        //all attributes of REFER_KEY
        //生成urlToRegistry,协议为consumer,具体的参数是RegistryURL中refer参数指定的参数
        Map<String, String> parameters = new HashMap<>(directory.getConsumerUrl().getParameters());
        URL urlToRegistry = new ServiceConfigURL(parameters.get(PROTOCOL_KEY) == null ? CONSUMER : parameters.get(PROTOCOL_KEY), parameters.remove(REGISTER_IP_KEY), 0, getPath(parameters, type), parameters);
        urlToRegistry = urlToRegistry.setScopeModel(directory.getConsumerUrl().getScopeModel());
        urlToRegistry = urlToRegistry.setServiceModel(directory.getConsumerUrl().getServiceModel());
        if (directory.isShouldRegister()) {
            //在urlToRegistry中添加category=consumers和check=false参数
            directory.setRegisteredConsumerUrl(urlToRegistry);
            //服务注册,在Zookeeper的consumers节点下,添加该Consumer对应的节点
            registry.register(directory.getRegisteredConsumerUrl());
        }

        //根据urlToRegistry创建服务路由
        directory.buildRouterChain(urlToRegistry);

        //订阅服务,toSubscribeUrl()方法会将urlToRegistry中category参数修改为"providers,configurators,routers"
        //DynamicDirectory子类RegistryDirectory的subscribe()会通过Registry订阅服务,同时还会添加相应的监听器
        directory.subscribe(toSubscribeUrl(urlToRegistry));

        //注册中心中可能包含多个Provider,相应的也就有多个Invoker
        //这里通过前面选择的cluster(即装饰着FailoverCluster的MockClusterWrapper)将多个Invoker对象封装成一个Invoker对象
        //所以下面首先会调用MockClusterWrapper的join()方法
        //最后返回的MockClusterInvoker会封装好DynamicDirectory和FailoverClusterInvoker
        return (ClusterInvoker<T>) cluster.join(directory, true);
    }
    ...
}

public class MockClusterWrapper implements Cluster {
    //包含一个故障转移集群FailoverCluster
    private final Cluster cluster;

    public MockClusterWrapper(Cluster cluster) {
        //Wrapper类都会有一个拷贝构造函数,装饰器模式
        this.cluster = cluster;
    }

    @Override
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
        //先调用AbstractCluster.join()方法处理传入的RegistryDirectory
        //然后用MockClusterInvoker进行包装,将DynamicDirectory和FailoverClusterInvoker包装在里面
        return new MockClusterInvoker<T>(directory, this.cluster.join(directory, buildFilterChain));
    }

    public Cluster getCluster() {
        return cluster;
    }
}

3.DynamicDirectory与Invoker的关系

DynamicDirectory的使用入口是RegistryProtocol的refer()方法:该方法首先会获取一个包含zk注册中心ZooKeeperRegistry的ListenerRegistryWrapper,然后会获取一个包含故障转移集群FailoverCluster的MockClusterWrapper,接着会调用interceptInvoker()方法加载相应的监听器实现,其中就包括了MigrationRuleListener监听器。

//-> ReferenceConfig.createInvokerForRemote()
//-> RegistryProtocol.refer()
//-> getRegistry() => ZooKeeperRegistry
//-> Cluster.getCluster() => MockClusterWrapper、FailoverCluster
//-> RegistryProtocol.doRefer()
//-> RegistryProtocol.getMigrationInvoker()
//-> RegistryProtocol.interceptInvoker()
//-> MigrationRuleListener.onRefer()

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //下面会返回一个MigrationInvoker,其构成是:
    //registry属性为装饰ZookeeperRegistry的ListenerRegistryWrapper
    //cluster属性为装饰FailoverCluster的MockCLusterWrapper
    //invoker和serviceDiscoveryInvoker属性都为MockClusterInvoker
    //其中前者的directory属性=注入了ZookeeperRegistry的RegistryDirectory
    //后者的directory属性=注入了ServiceDiscoveryRegistry的ServiceDiscoveryRegistryDirectory
    //但两者的invoker属性都是AbstractCluster的内部类ClusterFilterInvoker
    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        //从URL中获取注册中心的URL
        url = getRegistryUrl(url);

        //获取Registry实例,这里的RegistryFactory对象是通过Dubbo SPI的自动装载机制注入的
        //1.先拿到一个ListenerRegistryWrapper,里面包含一个zk注册中心ZooKeeperRegistry
        Registry registry = getRegistry(url);
        if (RegistryService.class.equals(type)) {
            return proxyFactory.getInvoker((T) registry, type, url);
        }

        //group="a,b" or group="*"
        //从注册中心URL的refer参数中获取此次服务引用的一些参数,其中就包括group
        Map<String, String> qs = (Map<String, String>) url.getAttribute(REFER_KEY);
        String group = qs.get(GROUP_KEY);
        if (StringUtils.isNotEmpty(group)) {
            if ((COMMA_SPLIT_PATTERN.split(group)).length > 1 || "*".equals(group)) {
                //如果此次可以引用多个group的服务,则Cluser实现使用MergeableCluster实现
                //这里的getMergeableCluster()方法就会通过Dubbo SPI方式找到MergeableCluster实例
                return doRefer(Cluster.getCluster(url.getScopeModel(), MergeableCluster.NAME), registry, type, url, qs);
            }
        }

        //2.接着会拿到一个MockClusterWrapper,里面会封装一个故障转移集群FailoverCluster
        //Cluster是和集群容错强相关的
        //不同的Cluster会对应不同的Cluster Invoker
        //不同的Cluster Invoker就有调用失败时不同的集群容错策略和算法
        Cluster cluster = Cluster.getCluster(url.getScopeModel(), qs.get(CLUSTER_KEY));

        //doRefer()这种代码的编写技巧在很多框架系统都会使用
        //refer()方法会先做一些提前的准备工作,而正式的工作会在方法名称的前面加一个do变成doRefer()方法来执行真正的工作
        //下面的doRefer()方法,执行时发现如果没有group参数或是group参数,则通过Cluster适配器选择Cluster实现
        return doRefer(cluster, registry, type, url, qs);
    }

    //doRefer()方法传入的参数cluster就是装饰着FailoverCluster的MockClusterWrapper
    //传入的参数registry为装饰ZookeeperRegistry的ListenerRegistryWrapper
    //这里会把组装好的Invoker体系里的最源头的一个Invoker进行返回,下一步就会去创建接口的动态代理并把该Invoker放进去
    //这样动态代理的方法被调用时,就可以通过该Invoker及其关联的Invoker来完成一个完整的RPC调用过程
    protected <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url, Map<String, String> parameters) {
        Map<String, Object> consumerAttribute = new HashMap<>(url.getAttributes());
        consumerAttribute.remove(REFER_KEY);
        String p = isEmpty(parameters.get(PROTOCOL_KEY)) ? CONSUMER : parameters.get(PROTOCOL_KEY);
        URL consumerUrl = new ServiceConfigURL(p, null, null, parameters.get(REGISTER_IP_KEY), 0, getPath(parameters, type), parameters, consumerAttribute);
        url = url.putAttribute(CONSUMER_URL_KEY, consumerUrl);

        //下面会以MigrationInvoker作为一个起点去构建一个Invoker链条;
        //这使用了经典的责任链模式,一环扣一环,先执行一个步骤再下一个步骤,把RPC调用的过程,一步步执行完毕;
        //但是在代码层面,却并非是严格的责任链模式来编码的,只是用到了这种责任链思想而已;
        //所以在这里会把不同的步骤和环节,拆分成不同的Invoker,把每个环节的代码逻辑内聚在单个Invoker内部;
        //再通过一系列的代码逻辑,把不同的环节的Invoker串联在一起,一个个按照顺序去串联;
        //这样真正执行时,就可以以MigrationInvoker作为一个起点,它会一个个的执行下一个Invoker;

        //下面这行代码可以理解为开始构建Invoker体系链条,也就是把源头Invoker给先准备好
        //传入的参数cluster就是装饰着FailoverCluster的MockClusterWrapper
        //getMigrationInvoker()所返回的MigrationInvoker中,它的invoker和serviceDiscoveryInvoker属性此时还是null
        ClusterInvoker<T> migrationInvoker = getMigrationInvoker(this, cluster, registry, type, url, consumerUrl);

        //接着下一步,要去继续组装后续的Invoker,然后把后续的Invoker构建好时,便设置给其上层Invoker;
        //所以在interceptInvoker()方法中,RegistryProtocol有责任在此把Invoker链条组装好;
        //但interceptInvoker字面上的意思就是拦截Invoker,字面上并不像是把后续的Invoker构建好设置给上层,有语义不清晰的嫌疑;

        //Invoker链条代表了RPC调用链路的全过程,每个步骤代表了一个环节,比如RPC调用过程里包含了如下环节:
        //migration(会有两个源头Invoker可以进行互相切换) -> mock降级 -> filter链条 -> 集群容错cluster -> 负载均衡 -> DubboInvoker
        //Dubbo应该针对每个环节进行对应的Invoker构建,并在每个环节的Invoker被构建好后,注入到上层的Invoker,从而完成Invoker链条的构建
        return interceptInvoker(migrationInvoker, url, consumerUrl);
    }

    protected <T> ClusterInvoker<T> getMigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        //构建基于服务发现机制迁移的Invoker
        //传入的cluster就是装饰着FailoverCluster的MockClusterWrapper
        //传入的registry为装饰ZookeeperRegistry的ListenerRegistryWrapper
        return new ServiceDiscoveryMigrationInvoker<T>(registryProtocol, cluster, registry, type, url, consumerUrl);
    }

    //这里首先会取出RegistryProtocol里的监听回调器
    //然后遍历监听回调器进行回调处理
    protected <T> Invoker<T> interceptInvoker(ClusterInvoker<T> invoker, URL url, URL consumerUrl) {
        //根据URL中的registry.protocol.listener参数加载相应的监听器实现
        //也就是RegistryProtocol里的监听回调器
        List<RegistryProtocolListener> listeners = findRegistryProtocolListeners(url);
        if (CollectionUtils.isEmpty(listeners)) {
            return invoker;
        }

        //此时传入的invoker也就是MigrationInvoker中
        //它的invoker和serviceDiscoveryInvoker属性此时还是null
        for (RegistryProtocolListener listener : listeners) {
            //传递给监听器,比如下面会调用MigrationRuleListener.onRefer()方法
            //事实上默认下listeners只有MigrationRuleListener一个元素
            listener.onRefer(this, invoker, consumerUrl, url);
        }

        //此时传入的invoker也就是MigrationInvoker中
        //它的invoker和serviceDiscoveryInvoker属性就都为MockClusterInvoker
        //其中前者的directory属性=RegistryDirectory
        //后者的directory属性=ServiceDiscoveryRegistryDirectory
        //但两者的invoker属性都是AbstractCluster的内部类ClusterFilterInvoker
        return invoker;
    }
    ...
}

public class MockClusterWrapper implements Cluster {
    //包含一个故障转移集群FailoverCluster
    private final Cluster cluster;
        
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
        //先调用AbstractCluster.join()方法处理传入的RegistryDirectory
        //然后用MockClusterInvoker进行包装,将DynamicDirectory和FailoverClusterInvoker包装在里面
        return new MockClusterInvoker<T>(directory, this.cluster.join(directory, buildFilterChain));
    }
    ...
}

public class ServiceDiscoveryMigrationInvoker<T> extends MigrationInvoker<T> {
    ...
    public ServiceDiscoveryMigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        super(registryProtocol, cluster, registry, type, url, consumerUrl);
    }
    ...
}

public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
    ...
    //服务引用时,它是一个故障转移的集群FailoverCluster
    private Cluster cluster;
    //服务引用时,它是一个服务注册中心ZooKeeperRegistry
    private Registry registry;
    //服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> invoker;
    //这是一个名为serviceDiscoveryInvoker的ClusterInvoker实现类的实例,也是一个MockClusterInvoker
    private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
    ...

    public MigrationInvoker(RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        this(null, null, registryProtocol, cluster, registry, type, url, consumerUrl);
    }

    public MigrationInvoker(ClusterInvoker<T> invoker, ClusterInvoker<T> serviceDiscoveryInvoker, RegistryProtocol registryProtocol, Cluster cluster, Registry registry, Class<T> type, URL url, URL consumerUrl) {
        //一开始创建MigrationInvoker时invoker属性是null
        //经过MigrationRuleListener.onRefer()方法的刷新后
        //也就是执行RegistryProtocol.doCreateInvoker()方法后
        //就会变为封装了DynamicDirectory和FailoverClusterInvoker的MockClusterInvoker
        this.invoker = invoker;
        //一开始创建MigrationInvoker时serviceDiscoveryInvoker属性是null
        //经过MigrationRuleListener.onRefer()方法的刷新后
        //也就是执行RegistryProtocol.doCreateInvoker()方法后
        //就会变为封装了DynamicDirectory和FailoverClusterInvoker的MockClusterInvoker
        this.serviceDiscoveryInvoker = serviceDiscoveryInvoker;
        this.registryProtocol = registryProtocol;
        //cluster就是装饰着FailoverCluster的MockClusterWrapper
        this.cluster = cluster;
        //registry是装饰着ZookeeperRegistry的ListenerRegistryWrapper
        this.registry = registry;
        ...
    }
}

MigrationRuleListener的onRefer()方法又会调用MigrationRuleHandler的doMigrate()方法。

MigrationRuleHandler的doMigrate()方法会调用MigrationRuleHandler的refreshInvoker()方法。

MigrationRuleHandler的refreshInvoker()方法会调用MigrationInvoker的refreshInterfaceInvoker()和refreshServiceDiscoveryInvoker()两个方法。MigrationInvoker的这两个方法又会调用RegistryProtocol的getInvoker()和getServiceDiscoveryInvoker()两个方法,也就是通过RegistryProtocol的doCreateInvoker()方法来刷新MigrationInvoker的invoker属性和serviceDiscoveryInvoker属性。

RegistryProtocol的doCreateInvoker()方法最终返回的是封装了DynamicDirectory和FailoverClusterInvoker的MockClusterInvoker,而MockClusterInvoker又会包含在MigrationInvoker里面。

//-> MigrationRuleListener.onRefer()
//-> MigrationRuleHandler.doMigrate()
//-> MigrationRuleListener.refreshInvoker()
//-> MigrationInvoker.refreshInterfaceInvoker() + MigrationInvoker.refreshServiceDiscoveryInvoker()
//-> RegistryProtocol.getInvoker() + RegistryProtocol.getServiceDiscoveryInvoker()
//-> RegistryProtocol.doCreateInvoker()

//该类用于监听配置中心里的MigrationRule迁移规则的变化
//由于MigrationRule迁移规则在consumer应用级别的范围都有效的
//所以MigrationRuleListener在所有的Invoker里都是有效的
//MigrationRuleListener是用来维系接口和handler之间的关系

//MigrationRuleListener会在如下两种情形下执行:
//1.当RegistryProtocol在refer()方法中针对MigrationInvoker进行回调处理时,会基于默认的迁移规则来决定Invoker后续的行为
//这说明了MigrationInvoker后续的一些行为都是由默认的迁移规则来指定的
//2.如果配置中心的迁移规则发生变化,此时Invoker后续的行为会由新规则来决定

//为什么要出现MigrationRuleListener这么一个监听器,通过该监听器来回调处理源头的MigrationInvoker?
//因为希望通过该监听器里的规则来决定MigrationInvoker后续的一些行为,也就是决定后续的一些Invoker的组装逻辑和行为
//从而对RPC调用过程产生影响,比如可以通过对这个规则进行监听,一旦规则变化则改变Invoker链条的行为

@Activate
public class MigrationRuleListener implements RegistryProtocolListener, ConfigurationListener {
    //默认的迁移规则
    private volatile MigrationRule rule;
    ...

    @Override
    public void onRefer(RegistryProtocol registryProtocol, ClusterInvoker<?> invoker, URL consumerUrl, URL registryURL) {
        MigrationRuleHandler<?> migrationRuleHandler = handlers.computeIfAbsent((MigrationInvoker<?>) invoker, _key -> {
            //给这个MigrationInvoker设置一个MigrationRuleListener,也就是当前的这个listener
            //此外还构建一个MigrationRuleHandler
            ((MigrationInvoker<?>) invoker).setMigrationRuleListener(this);
            return new MigrationRuleHandler<>((MigrationInvoker<?>) invoker, consumerUrl);
        });

        //然后拿默认构建好的迁移规则处理器,来执行对应的迁移逻辑:
        //rule=INIT规则,比如下面会调用MigrationRuleHandler.doMigrate()
        migrationRuleHandler.doMigrate(rule);
    }
    ...
}

public class MigrationRuleHandler<T> {
    ...
    public synchronized void doMigrate(MigrationRule rule) {
        ...
        if (refreshInvoker(step, threshold, rule)) {
            setMigrationRule(rule);
        }
    }

    private boolean refreshInvoker(MigrationStep step, Float threshold, MigrationRule newRule) {
        ...
        switch (step) {
            case APPLICATION_FIRST:
                //比如会调用MigrationInvoker.migrateToApplicationFirstInvoker()
                migrationInvoker.migrateToApplicationFirstInvoker(newRule);
                break;
            case FORCE_APPLICATION:
                //比如会调用MigrationInvoker.refreshServiceDiscoveryInvoker()
                success = migrationInvoker.migrateToForceApplicationInvoker(newRule);
                break;
            case FORCE_INTERFACE:
            default:
                //比如会调用MigrationInvoker.refreshInterfaceInvoker()
                success = migrationInvoker.migrateToForceInterfaceInvoker(newRule);
        }
        ...
    }
    ...
}

public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
    //服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> invoker;

    //这是一个名为serviceDiscoveryInvoker的ClusterInvoker实现类的实例,也是一个MockClusterInvoker
    private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
    ...

    @Override
    public void migrateToApplicationFirstInvoker(MigrationRule newRule) {
        CountDownLatch latch = new CountDownLatch(0);

        //这里是比较关键的:
        //migration迁移有两个核心的Invoker: InterfaceInvoker,ServiceDiscoveryInvoker;
        //下面会进行Invoker的刷新处理,就是在给我们的MigrationInvoker去注入下一环节的Invoker
        refreshInterfaceInvoker(latch);//第一个InterfaceInvoker
        refreshServiceDiscoveryInvoker(latch);//第二个ServiceDiscoveryInvoker

        //directly calculate preferred invoker, will not wait until address notify
        //calculation will re-occurred when address notify later
        //下面会把MigrationRule传递进去;
        //也就是当两个Invoker刷新好后,会根据最新的迁移规则来决定当前应该用哪个Invoker来作为MigrationInvoker的下一级Invoker;
        calcPreferredInvoker(newRule);
    }

    protected void refreshInterfaceInvoker(CountDownLatch latch) {
        ...
        //这里是核心逻辑
        //入参cluster是装饰着FailoverCluster的MockClusterWrapper
        //入参registry是装饰着ZookeeperRegistry的ListenerRegistryWrapper
        //下面会调用InterfaceCompatibleRegistryProtocol的getInvoker()方法
        //这个invoker其实最后发现就是FailoverClusterInvoker
        invoker = registryProtocol.getInvoker(cluster, registry, type, url);
        ...
    }

    protected void refreshServiceDiscoveryInvoker(CountDownLatch latch) {
        ...
        //比如下面会调用RegistryProtocol子类InterfaceCompatibleRegistryProtocol的getServiceDiscoveryInvoker()方法
        serviceDiscoveryInvoker = registryProtocol.getServiceDiscoveryInvoker(cluster, registry, type, url);
        ...
    }
    ...
}

public class InterfaceCompatibleRegistryProtocol extends RegistryProtocol {
    ...
    @Override
    public <T> ClusterInvoker<T> getInvoker(Cluster cluster, Registry registry, Class<T> type, URL url) {
        //这里传入的registry是ZookeeperRegistry
        DynamicDirectory<T> directory = new RegistryDirectory<>(type, url);

        //下面会调用RegistryProtocol的doCreateInvoker()方法
        return doCreateInvoker(directory, cluster, registry, type);
    }

    @Override
    public <T> ClusterInvoker<T> getServiceDiscoveryInvoker(Cluster cluster, Registry registry, Class<T> type, URL url) {
        //这个getRegistry()会获取到装饰着ServiceDiscoveryRegistry的ListenerRegistryWrapper,对传入的registry进行覆盖
        registry = getRegistry(super.getRegistryUrl(url));
        DynamicDirectory<T> directory = new ServiceDiscoveryRegistryDirectory<>(type, url);

        //下面会调用RegistryProtocol的doCreateInvoker()方法
        return doCreateInvoker(directory, cluster, registry, type);
    }
    ...
}

public class RegistryDirectory<T> extends DynamicDirectory<T> {
    ...
    ...
}

public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
    ...
    ...
}

//DynamicDirectory相当于2.7.x里的RegistryDirectory
//它是一个用来进行服务发现的组件,是一个可以动态管理可变的服务实例集群地址的组件
//当Consumer调用Provider时,便会用到该动态目录DynamicDirectory进行服务发现

//动态目录可以理解为:
//动态可变的一个目标服务实例的集群地址(invokers)
//有多少个目标服务实例就会有多少Invoker

//动态的意思其实就是:
//不仅可以通过主动查询来获取目标服务实例集群地址
//还可以在目标服务实例集群地址发生变化时,接收zk的推送并更新内存里的地址
public abstract class DynamicDirectory<T> extends AbstractDirectory<T> implements NotifyListener {
    ...
    ...
}

public class RegistryProtocol implements Protocol, ScopeModelAware {
    ...
    //入参directory是继承了DynamicDirectory的RegistryDirectory或者是继承了DynamicDirectory的ServiceDiscoveryRegistryDirectory
    //入参cluster是装饰着FailoverCluster的MockClusterWrapper
    protected <T> ClusterInvoker<T> doCreateInvoker(DynamicDirectory<T> directory, Cluster cluster, Registry registry, Class<T> type) {
        //设置注册中心
        directory.setRegistry(registry);

        //设置protocol协议
        directory.setProtocol(protocol);

        //all attributes of REFER_KEY
        //生成urlToRegistry,协议为consumer,具体的参数是RegistryURL中refer参数指定的参数
        Map<String, String> parameters = new HashMap<>(directory.getConsumerUrl().getParameters());
        URL urlToRegistry = new ServiceConfigURL(parameters.get(PROTOCOL_KEY) == null ? CONSUMER : parameters.get(PROTOCOL_KEY), parameters.remove(REGISTER_IP_KEY), 0, getPath(parameters, type), parameters);
        urlToRegistry = urlToRegistry.setScopeModel(directory.getConsumerUrl().getScopeModel());
        urlToRegistry = urlToRegistry.setServiceModel(directory.getConsumerUrl().getServiceModel());

        if (directory.isShouldRegister()) {
            //在urlToRegistry中添加category=consumers和check=false参数
            directory.setRegisteredConsumerUrl(urlToRegistry);
            //服务注册,在Zookeeper的consumers节点下,添加该Consumer对应的节点
            registry.register(directory.getRegisteredConsumerUrl());
        }

        //根据urlToRegistry创建服务路由
        directory.buildRouterChain(urlToRegistry);

        //订阅服务,toSubscribeUrl()方法会将urlToRegistry中category参数修改为"providers,configurators,routers"
        //DynamicDirectory子类RegistryDirectory的subscribe()会通过Registry订阅服务,同时还会添加相应的监听器
        directory.subscribe(toSubscribeUrl(urlToRegistry));

        //注册中心中可能包含多个Provider,相应的也就有多个Invoker
        //这里通过前面选择的cluster(即装饰着FailoverCluster的MockClusterWrapper)将多个Invoker对象封装成一个Invoker对象
        //所以下面首先会调用MockClusterWrapper的join()方法
        //最后返回的MockClusterInvoker会封装好DynamicDirectory和FailoverClusterInvoker
        return (ClusterInvoker<T>) cluster.join(directory, true);
    }
    ...
}

public class MockClusterWrapper implements Cluster {
    //包含一个故障转移集群FailoverCluster
    private final Cluster cluster;

    public MockClusterWrapper(Cluster cluster) {
        //Wrapper类都会有一个拷贝构造函数,装饰器模式
        this.cluster = cluster;
    }

    @Override
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
        //先调用AbstractCluster.join()方法处理传入的RegistryDirectory
        //然后用MockClusterInvoker进行包装,将DynamicDirectory和FailoverClusterInvoker包装在里面
        return new MockClusterInvoker<T>(directory, this.cluster.join(directory, buildFilterChain));
    }

    public Cluster getCluster() {
        return cluster;
    }
}

public abstract class AbstractCluster implements Cluster {
    ...
    @Override
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
        //比如下面会执行FailoverCluster的doJoin()方法
        if (buildFilterChain) {
            return buildClusterInterceptors(doJoin(directory));
        } else {
            return doJoin(directory);
        }
    }

    private <T> Invoker<T> buildClusterInterceptors(AbstractClusterInvoker<T> clusterInvoker) {
        //服务引用时这里传入的clusterInvoker会为FailoverClusterInvoker
        //然后构建出一个AbstractCluster的内部类ClusterFilterInvoker
        AbstractClusterInvoker<T> last = buildInterceptorInvoker(new ClusterFilterInvoker<>(clusterInvoker));
        return last;
    }

    private <T> AbstractClusterInvoker<T> buildInterceptorInvoker(AbstractClusterInvoker<T> invoker) {
        //通过SPI方式加载InvocationInterceptorBuilder扩展实现
        //在服务引用时默认情况下,下面获取到的builders为空
        //框架没提供InvocationInterceptorBuilder的默认实现
        List<InvocationInterceptorBuilder> builders = ScopeModelUtil.getApplicationModel(invoker.getUrl().getScopeModel()).getExtensionLoader(InvocationInterceptorBuilder.class).getActivateExtensions();
        if (CollectionUtils.isEmpty(builders)) {
            return invoker;
        }
        return new InvocationInterceptorInvoker<>(invoker, builders);
    }

    protected abstract <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException;
    ...
}

public class FailoverCluster extends AbstractCluster {
    public final static String NAME = "failover";

    @Override
    public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
        //执行RegistryProtocol.refer()时,这里传入的directory会是RegistryDirectory
        //这里会创建出一个FailoverClusterInvoker,同时把directory传入FailoverClusterInvoker
        return new FailoverClusterInvoker<>(directory);
    }
}

public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
    ...
    public FailoverClusterInvoker(Directory<T> directory) {
        super(directory);
    }
    ...
}

public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
    protected Directory<T> directory;
    ...

    public AbstractClusterInvoker(Directory<T> directory) {
        this(directory, directory.getUrl());
    }

    public AbstractClusterInvoker(Directory<T> directory, URL url) {
        ...
        this.directory = directory;
        ...
    }
    ...
}

public class MockClusterInvoker<T> implements ClusterInvoker<T> {
    private final Directory<T> directory;
    private final Invoker<T> invoker;

    public MockClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
        //传入的directory为DynamicDirectory
        //当初始化MigrationInvoker.invoker时,传入的directory为RegistryDirectory
        //当初始化MigrationInvoker.serviceDiscoveryInvoker时,传入的directory为ServiceDiscoveryRegistryDirectory
        //不管是RegistryDirectory,还是ServiceDiscoveryRegistryDirectory,其实都是DynamicDirectory
        this.directory = directory;

        //传入的invoker为AbstractCluster的内部类ClusterFilterInvoker
        //其filterInvoker属性的originalInvoker属性便为封装了DynamicDirectory的FailoverClusterInvoker
        this.invoker = invoker;
    }
    ...
}

4.基于Invoker来创建动态代理对象

ReferenceConfig的createProxy()方法的最后一行代码,会基于Invoker创建一个动态代理对象。

public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
    //The invoker of the reference service
    private transient volatile Invoker<?> invoker;
    ...

    private T createProxy(Map<String, String> referenceParameters) {
        //provider端有一个本地发布的动作;
        //本地发布即把目标实现类封装成一个ProxyInvoker,然后再通过InjvmProtocol发布出去,也就是把ProxyInvoker封装成InjvmExporter;
        //所以在同一个JVM里进行本地服务调用时,调用的便是本地发布出去的provider服务实例

        //根据url的协议、scope以及injvm等参数检测是否需要本地引用
        if (shouldJvmRefer(referenceParameters)) {
            createInvokerForLocal(referenceParameters);
        } else {
            urls.clear();
            meshModeHandleUrl(referenceParameters);
            if (StringUtils.isNotEmpty(url)) {
                //user specified URL, could be peer-to-peer address, or register center's address.
                //解析用户指定的URL,可能是一个点对点的调用地址,或者是一个注册中心的地址
                parseUrl(referenceParameters);
            } else {
                //if protocols not in jvm checkRegistry
                if (!LOCAL_PROTOCOL.equalsIgnoreCase(getProtocol())) {
                    //加载注册中心的地址RegistryURL
                    aggregateUrlFromRegistry(referenceParameters);
                }
            }
            //接下来是核心源码的第一步,通过RegistryProtocol创建invoker
            createInvokerForRemote();
        }
        ...

        //这些都是url的处理
        URL consumerUrl = new ServiceConfigURL(CONSUMER_PROTOCOL, referenceParameters.get(REGISTER_IP_KEY), 0, referenceParameters.get(INTERFACE_KEY), referenceParameters);
        consumerUrl = consumerUrl.setScopeModel(getScopeModel());
        consumerUrl = consumerUrl.setServiceModel(consumerModel);
        //对于Consumer的元数据,会通过如下代码在这里进行发布
        MetadataUtils.publishServiceDefinition(consumerUrl, consumerModel.getServiceModel(), getApplicationModel());

        //create service proxy
        //通过ProxyFactory适配器选择合适的ProxyFactory扩展实现,基于Invoker创建动态代理对象
        //接下来会调用ProxyFactory$Adaptive.getProxy() -> StubProxyFactoryWrapper.getProxy()
        return (T) proxyFactory.getProxy(invoker, ProtocolUtils.isGeneric(generic));
    }

    private void createInvokerForRemote() {
        //createInvokerForRemote核心就两个步骤:
        //第一是执行RegistryProtocol.refer()构建出一个invoker;
        //第二是执行Cluster.getCluster().join() + new StaticDirectory()对invokers进行加工处理,最后覆盖到invoker上;
        //protocolSPI.refer -> invokers -> new StaticDirectory() -> cluster.join -> invoker
        if (urls.size() == 1) {
            //在单注册中心或是直连单个服务提供方的时候,通过Protocol的适配器选择对应的Protocol实现创建Invoker对象
            //也就是会基于RegistryProtocol.refer构建出一个Invoker(比如dubbo-demo-api下的示例会构建出一个MigrationInvoker,且curUrl不是注册中心的)
            //而且该MigrationInvoker构成:registry属性为装饰ZookeeperRegistry的ListenerRegistryWrapper + cluster属性为装饰FailoverCluster的MockCLusterWrapper
            ...
            invoker = protocolSPI.refer(interfaceClass, curUrl);
            invokers.add(invoker);
            //对Invoker进行了一个深加工和处理,又拿到了一个Invoker,覆盖赋值处理
            invoker = Cluster.getCluster(scopeModel, Cluster.DEFAULT).join(new StaticDirectory(curUrl, invokers), true);
            ...
        } else {
            //多注册中心或是直连多个服务提供方的时候,会根据每个URL创建Invoker对象
            for (URL url : urls) {
                invokers.add(protocolSPI.refer(interfaceClass, url));
                ...
            }
            if (registryUrl != null) {
                ...
                invoker = Cluster.getCluster(registryUrl.getScopeModel(), cluster, false).join(new StaticDirectory(registryUrl, invokers), false);
            } else {
                ...
                invoker = Cluster.getCluster(scopeModel, cluster).join(new StaticDirectory(curUrl, invokers), true);          
            }
        }
        ...
    }
    ...
}

最后一行代码"proxyFactory.getProxy()"最终会调用StubProxyFactoryWrapper的getProxy()方法,该方法生成的动态代理类主要实现了如下三个接口:

1.org.apache.dubbo.demo.DemoService
2.org.apache.dubbo.rpc.service.EchoService
3.org.apache.dubbo.rpc.service.Destoryable
//-> ReferenceConfig.createProxy()
//-> ReferenceConfig.createInvokerForRemote()
//-> protocolSPI.refer()
//-> proxyFactory.getProxy()
//-> ProxyFactory$Adaptive.getProxy()
//-> StubProxyFactoryWrapper.getProxy()
//-> AbstractProxyFactory.getProxy()
//-> JavassistProxyFactory.getProxy()
//-> Proxy.getProxy()
//-> new InvokerInvocationHandler()

public class StubProxyFactoryWrapper implements ProxyFactory {
    //包含一个JavassistProxyFactory
    private final ProxyFactory proxyFactory;
    private Protocol protocol;

    public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
        this.proxyFactory = proxyFactory;
    }

    public void setProtocol(Protocol protocol) {
        this.protocol = protocol;
    }

    @Override
    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
        //为什么它的名字叫stub打桩?
        //stub这个名字一般代表的是远程网络访问的动态代理
        //通过这个stub可以对远程的机器进行网络访问
        //stub打桩思想,是在网络远程访问里经常会使用的一种方法,类似于电线杆打桩一样
        //比如机器A和机器B之间进行的远程网络访问,必然要通过网络来进行连接和访问
        //机器A在进行远程RPC访问时,其调用代码,最好不要直接写网络通信的逻辑,而是写针对某个接口类型对象的方法调用
        //这样在机器A上面进行RPC调用时就像是在本地调用一样,都是直接调用某个对象的方法
        //然后在这个对象的方法里,再去写网络通信的逻辑和目标机器B进行网络连接,并发送调用请求
        //所以在机器A上会针对调用的那个接口,来动态去生成一个实现了该接口的类,也就是动态代理的代理类或者是stub打桩
        //类似于在机器A上打下的一个伪装成目标类的桩,然后针对打的这个stub桩去进行调用,stub内部会编写网络通信代码实现跨机器的访问
        //这就是远程网络连接和通信的stub打桩思想
        //下面使用了抽象代理工厂来获取真正的动态代理
        //下面会调用JavassistProxyFactory的getProxy()方法
        //也就是调用AbstractProxyFactory的getProxy()方法
        T proxy = proxyFactory.getProxy(invoker, generic);
        ...

        return proxy;
    }
    ...
}

public abstract class AbstractProxyFactory implements ProxyFactory {
    ...
    @Override
    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
        //记录要代理的接口
        LinkedHashSet<Class<?>> interfaces = new LinkedHashSet<>();
        ClassLoader classLoader = getClassLoader(invoker);

        //获取URL中interfaces参数指定的接口
        String config = invoker.getUrl().getParameter(INTERFACES);
        if (StringUtils.isNotEmpty(config)) {
            //按照逗号切分interfaces参数,得到接口集合,然后进行遍历
            String[] types = COMMA_SPLIT_PATTERN.split(config);

            //遍历接口集合,并记录这些接口信息
            for (String type : types) {
                //对每个接口都拿出对应的class对象,放到interfaces集合里
                interfaces.add(ReflectUtils.forName(classLoader, type));
            }
        }
        ...

        //获取Invoker中type字段指定的接口
        interfaces.add(invoker.getInterface());

        //添加EchoService、Destroyable两个默认接口
        interfaces.addAll(Arrays.asList(INTERNAL_INTERFACES));

        //调用抽象的getProxy()重载方法
        //Dubbo的动态代理技术有如下两种:
        //一.javassist(动态拼接类的代码字符串,通过动态编译来动态生成一个类)
        //二.jdk(通过jdk提供的API利用反射来生成动态代理)
        //默认下面会调用子类JavassistProxyFactory的getProxy()方法
        return getProxy(invoker, interfaces.toArray(new Class<?>[0]));
    }

    public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types);
    ...
}

public class JavassistProxyFactory extends AbstractProxyFactory {
    private final static Logger logger = LoggerFactory.getLogger(JavassistProxyFactory.class);
    private final JdkProxyFactory jdkProxyFactory = new JdkProxyFactory();

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        try {
            //下面的Proxy是Dubbo自己实现的Proxy
            return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
        } catch (Throwable fromJavassist) {
            //try fall back to JDK proxy factory
            try {
                T proxy = jdkProxyFactory.getProxy(invoker, interfaces);
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy success. " + "Interfaces: " + Arrays.toString(interfaces), fromJavassist);
                return proxy;
            } catch (Throwable fromJdk) {
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + "Interfaces: " + Arrays.toString(interfaces) + " Javassist Error.", fromJavassist);
                logger.error("Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + "Interfaces: " + Arrays.toString(interfaces) + " JDK Error.", fromJdk);
                throw fromJavassist;
            }
        }
    }
    ...
}

public class Proxy {
    private static final Map<ClassLoader, Map<String, Proxy>> PROXY_CACHE_MAP = new WeakHashMap<>();
    ...

    public static Proxy getProxy(Class<?>... ics) {
        ...
        //ClassLoader from App Interface should support load some class from Dubbo
        ClassLoader cl = ics[0].getClassLoader();
        ProtectionDomain domain = ics[0].getProtectionDomain();

        //use interface class name list as key.
        //生成的动态代理类主要实现了如下三个接口:
        //1.org.apache.dubbo.demo.DemoService
        //2.org.apache.dubbo.rpc.service.EchoService
        //3.org.apache.dubbo.rpc.service.Destoryable
        String key = buildInterfacesKey(cl, ics);

        //get cache by class loader.
        final Map<String, Proxy> cache;
        synchronized (PROXY_CACHE_MAP) {
            cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new ConcurrentHashMap<>());
        }

        //接口列表将会作为第二层集合的Key
        Proxy proxy = cache.get(key);
        if (proxy == null) {
            synchronized (ics[0]) {
                proxy = cache.get(key);
                if (proxy == null) {
                    //create Proxy class.
                    proxy = new Proxy(buildProxyClass(cl, ics, domain));
                    cache.put(key, proxy);
                }
            }
        }
        return proxy;
    }

    private static Class<?> buildProxyClass(ClassLoader cl, Class<?>[] ics, ProtectionDomain domain) {
        ClassGenerator ccp = null;
        ccp = ClassGenerator.newInstance(cl);
        Set<String> worked = new HashSet<>();
        List<Method> methods = new ArrayList<>();
        String pkg = ics[0].getPackage().getName();
        Class<?> neighbor = ics[0];

        for (Class<?> ic : ics) {
            String npkg = ic.getPackage().getName();
            //向ClassGenerator中添加接口
            ccp.addInterface(ic);

            //遍历接口中的每个方法
            for (Method method : ic.getMethods()) {
                String desc = ReflectUtils.getDesc(method);
                //跳过已经重复方法以及static方法
                if (worked.contains(desc) || Modifier.isStatic(method.getModifiers())) {
                    continue;
                }
                //将方法描述添加到worked这个Set集合中,进行去重
                worked.add(desc);

                int ix = methods.size();
                //获取方法的返回值
                Class<?> rt = method.getReturnType();
                //获取方法的参数列表
                Class<?>[] pts = method.getParameterTypes();
                //创建方法体
                StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
                for (int j = 0; j < pts.length; j++) {
                    code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(';');
                }
                code.append(" Object ret = handler.invoke(this, methods[").append(ix).append("], args);");
                //生成return语句
                if (!Void.TYPE.equals(rt)) {
                    code.append(" return ").append(asArgument(rt, "ret")).append(';');
                }
                //将生成好的方法添加到ClassGenerator中缓存
                methods.add(method);
                ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
            }
        }

        //create ProxyInstance class.
        //生成并设置代理类类名
        String pcn = neighbor.getName() + "DubboProxy" + PROXY_CLASS_COUNTER.getAndIncrement();
        ccp.setClassName(pcn);

        //添加字段
        //一个是前面生成的methods集合
        //另一个是InvocationHandler对象
        ccp.addField("public static java.lang.reflect.Method[] methods;");
        ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
        //添加构造方法
        ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
        //默认构造方法
        ccp.addDefaultConstructor();
        Class<?> clazz = ccp.toClass(neighbor, cl, domain);
        clazz.getField("methods").set(null, methods.toArray(new Method[0]));
        return clazz;
    }
    ...
}

//实现了JDK反射机制里的InvocationHandler接口
public class InvokerInvocationHandler implements InvocationHandler {
    ...

    public InvokerInvocationHandler(Invoker<?> handler) {
        this.invoker = handler;
        URL url = invoker.getUrl();
        this.protocolServiceKey = url.getProtocolServiceKey();
        this.serviceModel = url.getServiceModel();
    }

    //通过这个代理对象可以拿到这个代理对象的接口
    //通过接口就可以定位到目标服务实例发布的服务接口,从而针对目标服务实例进行调用
    //拿到了调用目标服务实例的方法、传递进去的参数等信息,就可以进行完整的RPC调用
    //动态代理就是针对接口动态去生成该接口的实现类并进行调用

    //比如针对DemoService这个接口去生成一个实现类
    //由于这个实现类是动态生成的,那么它如何知道会有调用方去调用它的方法,以及又如何去执行?
    
    //为此,动态代理底层都会封装InvocationHandler
    //封装完后对动态代理所有方法的调用,都会跑到InvocationHandler这里来
    
    //这样,InvocationHandler的invoke方法就可以拿到:
    //Proxy动态代理对象、需要调用对象的哪个方法Method、以及被调用方法会传入的参数args
    
    //此时,对动态代理不同方法的调用以及具体方法被调用后会如何处理
    //都可以由如下invoke()方法发起远程调用由服务提供者来决定
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //对于Object中定义的方法,直接调用Invoker对象的相应方法即可
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(invoker, args);
        }
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (parameterTypes.length == 0) {
            if ("toString".equals(methodName)) {
                //对toString()方法进行特殊处理
                return invoker.toString();
            } else if ("$destroy".equals(methodName)) {
                //对$destroy等方法的特殊处理
                invoker.destroy();
                return null;
            } else if ("hashCode".equals(methodName)) {
                //对hashCode()方法进行特殊处理
                return invoker.hashCode();
            }
        } else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
            return invoker.equals(args[0]);
        }

        //创建RpcInvocation对象,后面会作为远程RPC调用的参数
        //Consumer端进行RPC调用时,必须要封装一个RpcInvocation
        //这个RpcInvocation会传递到Provider端
        //Provider端拿到请求数据后,也会封装一个RpcInvocation
        RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, method.getName(), invoker.getInterface().getName(), protocolServiceKey, method.getParameterTypes(), args);

        if (serviceModel instanceof ConsumerModel) {
            rpcInvocation.put(Constants.CONSUMER_MODEL, serviceModel);
            rpcInvocation.put(Constants.METHOD_MODEL, ((ConsumerModel) serviceModel).getMethodModel(method));
        }

        //调用invoke()方法发起远程调用
        //拿到AsyncRpcResult之后,调用recreate()方法获取响应结果(或是Future)
        //下面的invoker其实就是装饰了MockClusterInvoker的MigrationInvoker
        return InvocationUtil.invoke(invoker, rpcInvocation);
    }
}

5.动态代理生成后检查Invoker是否有效

public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
    ...
    protected synchronized void init() {
        ...
        //执行服务实例的刷新操作
        //也就是刷新ProviderConfig -> MethodConfig -> ArgumentConfig
        if (!this.isRefreshed()) {
            this.refresh();
        }

        //init serviceMetadata
        //对Metadata元数据进行初始化以及存储注册等一系列的操作
        //封装一个ConsumerModel,即把Consumer的数据封装起来放到对应的repository里
        initServiceMetadata(consumer);
        ...

        //调用ReferenceConfig的createProxy()方法创建服务的动态代理对象
        //这是构建整个代理的入口
        ref = createProxy(referenceParameters);

        //创建完动态代理后,把这个代理设置给serviceMetadata以及consumerModel
        serviceMetadata.setTarget(ref);
        serviceMetadata.addAttribute(PROXY_CLASS_REF, ref);

        consumerModel.setDestroyRunner(getDestroyRunner());
        consumerModel.setProxyObject(ref);
        consumerModel.initMethodModels();

        //检查一下Invoker是否可用
        checkInvokerAvailable();
    }

    private void checkInvokerAvailable() throws IllegalStateException {
        //根据check配置决定是否检测Provider是否可用
        //下面的invoker.isAvailable()调用的是MigrationInvoker的isAvailable()方法
        if (shouldCheck() && !invoker.isAvailable()) {
            //2-2 - No provider available.
            ...
            throw illegalStateException;
        }
    }
    ...
}

public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
    //服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> invoker;
    //这是一个名为serviceDiscoveryInvoker的ClusterInvoker实现类的实例,也是一个MockClusterInvoker
    private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
    //表示当前使用的Invoker,服务引用时,它是一个MockClusterInvoker
    private volatile ClusterInvoker<T> currentAvailableInvoker;
    ...

    @Override
    public boolean isAvailable() {
        //currentAvailableInvoker.isAvailable()会调用到MockClusterInvoker.isAvailable()的方法
        //最后又会调用RegistryDirectory.isAvailable()的方法
        return currentAvailableInvoker != null
            ? currentAvailableInvoker.isAvailable()
            : (invoker != null && invoker.isAvailable()) 
            || (serviceDiscoveryInvoker != null && serviceDiscoveryInvoker.isAvailable());
    }
    ...
}

当Invoker的检查执行完毕后,就表示如下代码中"reference.get()"已执行完毕,已经生成好了动态代理的接口,于是可以继续往下执行。

当后续调用动态代理的接口时,便会进入InvokerInvocationHandler的invoke()方法中。

public class Application {
    public static void main(String[] args) throws Exception {
        //Reference和ReferenceConfig是什么
        //Reference是一个引用,是对Provider端的一个服务实例的引用
        //ReferenceConfig这个服务实例的引用的一些配置
        //通过泛型传递了这个服务实例对外暴露的接口
        ReferenceConfig<DemoService> reference = new ReferenceConfig<>();

        //设置应用名称
        reference.setApplication(new ApplicationConfig("dubbo-demo-api-consumer"));

        //设置注册中心的地址,默认是ZooKeeper
        reference.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));

        //设置元数据上报地址
        reference.setMetadataReportConfig(new MetadataReportConfig("zookeeper://127.0.0.1:2181"));

        //设置要调用的服务的接口
        reference.setInterface(DemoService.class);

        //直接通过ReferenceConfig的get()方法来拿到一个DemoService接口
        //它是一个动态代理接口,只要被调用,便会通过底层调用Provider服务实例的对应接口
        DemoService service = reference.get();

        //下面调用动态代理的接口
        //会进入InvokerInvocationHandler的invoke()方法中
        String message = service.sayHello("dubbo");

        System.out.println(message);
        Thread.sleep(10000000L);
    }
}

//实现了JDK反射机制里的InvocationHandler接口
public class InvokerInvocationHandler implements InvocationHandler {
    ...

    public InvokerInvocationHandler(Invoker<?> handler) {
        this.invoker = handler;
        URL url = invoker.getUrl();
        this.protocolServiceKey = url.getProtocolServiceKey();
        this.serviceModel = url.getServiceModel();
    }

    //通过这个代理对象可以拿到这个代理对象的接口
    //通过接口就可以定位到目标服务实例发布的服务接口,从而针对目标服务实例进行调用
    //拿到了调用目标服务实例的方法、传递进去的参数等信息,就可以进行完整的RPC调用
    //动态代理就是针对接口动态去生成该接口的实现类并进行调用

    //比如针对DemoService这个接口去生成一个实现类
    //由于这个实现类是动态生成的,那么它如何知道会有调用方去调用它的方法,以及又如何去执行?

    //为此,动态代理底层都会封装InvocationHandler
    //封装完后对动态代理所有方法的调用,都会跑到InvocationHandler这里来

    //这样,InvocationHandler的invoke方法就可以拿到:
    //Proxy动态代理对象、需要调用对象的哪个方法Method、以及被调用方法会传入的参数args

    //此时,对动态代理不同方法的调用以及具体方法被调用后会如何处理
    //都可以由如下invoke()方法发起远程调用由服务提供者来决定
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //对于Object中定义的方法,直接调用Invoker对象的相应方法即可
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(invoker, args);
        }
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (parameterTypes.length == 0) {
            if ("toString".equals(methodName)) {
                //对toString()方法进行特殊处理
                return invoker.toString();
            } else if ("$destroy".equals(methodName)) {
                //对$destroy等方法的特殊处理
                invoker.destroy();
                return null;
            } else if ("hashCode".equals(methodName)) {
                //对hashCode()方法进行特殊处理
                return invoker.hashCode();
            }
        } else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
            return invoker.equals(args[0]);
        }

        //创建RpcInvocation对象,后面会作为远程RPC调用的参数
        //Consumer端进行RPC调用时,必须要封装一个RpcInvocation
        //这个RpcInvocation会传递到Provider端
        //Provider端拿到请求数据后,也会封装一个RpcInvocation
        RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, method.getName(), invoker.getInterface().getName(), protocolServiceKey, method.getParameterTypes(), args);

        if (serviceModel instanceof ConsumerModel) {
            rpcInvocation.put(Constants.CONSUMER_MODEL, serviceModel);
            rpcInvocation.put(Constants.METHOD_MODEL, ((ConsumerModel) serviceModel).getMethodModel(method));
        }

        //调用invoke()方法发起远程调用
        //拿到AsyncRpcResult之后,调用recreate()方法获取响应结果(或是Future)
        //下面的invoker其实就是装饰了MockClusterInvoker的MigrationInvoker
        return InvocationUtil.invoke(invoker, rpcInvocation);
    }
}