Dubbo服务提供者、服务消费者的代理

159 阅读1分钟

在Dubbo中,代理被分为两类,一个是服务提供方使用Wrapper生成的代理,一个是服务消费者使用Proxy生成的代理。

1.服务消费者的代理源码

在服务启动时,服务被实例化时会调用ReferenceConfig类的

private T createProxy(Map<String, String> map) {
    //调用ProxyFactory接口的实现类JavassistProxyFactory
    //进行创建代理对象
    return (T) PROXY_FACTORY.getProxy(invoker);
}

方法,这里会对服务进行代理,最终在Spring中注入的对象是一个代理对象。

2.服务提供者的代理源码

服务启动时进行暴露服务,这里会通过ServiceConfig的exportLocal方法进行服务暴露,

private void exportLocal(URL url) {
    URL local = URLBuilder.from(url)
            .setProtocol(LOCAL_PROTOCOL)
            .setHost(LOCALHOST_VALUE)
            .setPort(0)
            .build();
            //下面传入的是一个invoker,invoker又是ProxyFactory进行创建的
    Exporter<?> exporter = protocol.export(
            PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, local));
    exporters.add(exporter);

}

最终会通过SPI机制默认选择JavassistProxyFactory作为实现类进行代理操作。

public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
    // TODO Wrapper cannot handle this scenario correctly: the classname contains '$'
    //这里就是创建代理对象的逻辑,最后返回的是一个Wrapper
    final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
    return new AbstractProxyInvoker<T>(proxy, type, url) {
        @Override
        protected Object doInvoke(T proxy, String methodName,
                                  Class<?>[] parameterTypes,
                                  Object[] arguments) throws Throwable {
            return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
        }
    };
}