【dubbo源码分析】5. dubbo消费端 - ProxyFactory使用 Invoker创建消费端调用代理类

11 篇文章 0 订阅
首先来看看proxyFactory:
 private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
根据 Adaptive类/com.alibaba.dubbo.rpc.ProxyFactory 之 Adaptive类 文章可知,proxyFactory的Adaptive类主要方法及逻辑如下:
public class ProxyFactory$Adaptive implements com.alibaba.dubbo.rpc.ProxyFactory {
	public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
  com.alibaba.dubbo.common.URL url = arg0.getUrl();
		String extName = url.getParameter("proxy", "javassist");
		com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
		return extension.getProxy(arg0);
	}
	public com.alibaba.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, com.alibaba.dubbo.common.URL arg2) throws com.alibaba.dubbo.rpc.RpcException {
		com.alibaba.dubbo.common.URL url = arg2;
		String extName = url.getParameter("proxy", "javassist");
		com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
		return extension.getInvoker(arg0, arg1, arg2);
	}
}

由此可知, proxyFactory.getProxy(Invoker invoker) 最终交由 JavassistProxyFaactory.getProxy(Invoker) 处理,又因为有ProxyFactory 实例包装类 StubProxyFactoryWrapper ,因此
ProxyFactory$Adaptive .getProxy(invoker) 方法中 com.alibaba.dubbo.rp c.ProxyFactory extension = new StubProxyFactoryWrapper (JavassistProxyFactory);
因此调用链为 StubProxyFactoryWrapper .getProxy() -> JavassistProxyFactory .getProxy() -> return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)) ;
处理流程图如下:



下面看看 JavassistProxyFactory .getProxy(Invoker invoker)

这里需要注意的是,生成的consumer代理除了实现指定接口外,还需要实现EchoService(支持回声测深,用于检查服务是否可用)。接下来就是真正的代理类生成了
我们看Proxy.getProxy(interfaces)方法:
public static Proxy getProxy(Class<?>... ics) {
        return getProxy(ClassHelper.getClassLoader(Proxy.class), ics);
  }
  public static Proxy getProxy(ClassLoader cl, Class<?>... ics) {
........
//关键代码
String pkg = null;
        ClassGenerator ccp = null, ccm = null;
        try {
            ccp = ClassGenerator.newInstance(cl);

            Set<String> worked = new HashSet<String>();
            List<Method> methods = new ArrayList<Method>();

            for (int i = 0; i < ics.length; i++) {
                if (!Modifier.isPublic(ics[i].getModifiers())) {
                    String npkg = ics[i].getPackage().getName();
                    if (pkg == null) {
                        pkg = npkg;
                    } else {
                        if (!pkg.equals(npkg))
                            throw new IllegalArgumentException("non-public interfaces from different packages");
                    }
                }
                ccp.addInterface(ics[i]); //此处循环将方法传入的interfaces添加 (即实现所有传入的接口 implements Interface1,interface2)

                for (Method method : ics[i].getMethods()) {
                    String desc = ReflectUtils.getDesc(method);
                    if (worked.contains(desc))
                        continue;
                    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[" + ix + "], args);");
                    if (!Void.TYPE.equals(rt))
                        code.append(" return ").append(asArgument(rt, "ret")).append(";");

                    methods.add(method);
                    ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());  //此处将传入的接口里所有接口方法进行实现(即 @override)
                }
            }

            if (pkg == null)
                pkg = PACKAGE_NAME;

            // create ProxyInstance class.  开始生成consumer接口代理类(生成的代码逻辑见代码1)
            String pcn = pkg + ".proxy" + id;
            ccp.setClassName(pcn);
            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();
            clazz.getField("methods").set(null, methods.toArray(new Method[0]));

            // create Proxy class.  此处代码逻辑开始生成 抽象类 Proxy  的实现类(代码见 代码2)
            String fcn = Proxy.class.getName() + id;
            ccm = ClassGenerator.newInstance(cl);
            ccm.setClassName(fcn);
            ccm.addDefaultConstructor();
            ccm.setSuperClass(Proxy.class);
            ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
            Class<?> pc = ccm.toClass();
            proxy = (Proxy) pc.newInstance();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            // release ClassGenerator
            if (ccp != null)
                ccp.release();
            if (ccm != null)
                ccm.release();
            synchronized (cache) {
                if (proxy == null)
                    cache.remove(key);
                else
                    cache.put(key, new WeakReference<Proxy>(proxy));
                cache.notifyAll();
            }
        }
        return proxy;
}
最终生成的消费端服务代理类( 代码1 )如下:
package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.demo.DemoService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

// 见com.alibaba.dubbo.common.bytecode.Proxy.getProxy
public class proxy0 implements ClassGenerator.DC, EchoService, DemoService {
  // methods包含proxy0实现的所有接口方法(去重)
  public static Method[] methods;   //methods = {syaHello,$echo}
  private InvocationHandler handler;

  public String sayHello(String arg0) {
    Object[] args = new Object[1];
    args[0] = arg0;
    Object localObject = this.handler.invoke(this, methods[0], args);
    return (String)localObject;
  }

  public Object $echo(Object arg0) {
    Object[] args = new Object[1];
    args[0] = arg0;
    Object localObject = this.handler.invoke(this, methods[1], args);
    return (Object)localObject;
  }

  public proxy0() {
  }

  public proxy0(InvocationHandler paramInvocationHandler) {
    this.handler = paramInvocationHandler;
  }
}
和抽象类Proxy的子类( 代码2 ):
com.alibaba.dubbo.common.bytecode.Proxy0 extends Proxy {
public Proxy0(){
}
	
public Object newInstance(java.lang.reflect.InvocationHandler h){ 
		return new com.alibaba.dubbo.common.bytecode.proxy0($1);  //$1 即为方法入参1
	}
}
因此
JavassistProxtFactory{
 public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }
}
首先 Proxy.getProxy(interfaces) 会先返回抽象类 Proxy的 实现类 Proxy0 ( 见代码2 );接着调用 newInstance(InvokerInvocationHandler handler)
返回consumer服务代理类 new com.alibaba.dubbo.common.bytecode.proxy0( new InvokerInvocationHandler(invoker) )
因此最终返回至 StubProxyFactoryWrapper 的 T proxy = proxyFactory.getProxy(invoker); 为 new com.alibaba.dubbo.common.bytecode.proxy0( new InvokerInvocationHandler(invoker) ) ;
proxy0 包含了DemoService服务接口的方法实现( 见代码1

下面来看StubProxyFactoryWrapper 在获取到 consumer服务代理后进行哪些改造:
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
        T proxy = proxyFactory.getProxy(invoker);//获取consumer服务代理类
        if (GenericService.class != invoker.getInterface()) {
            String stub = invoker.getUrl().getParameter(Constants.STUB_KEY, invoker.getUrl().getParameter(Constants.LOCAL_KEY)); //url中设置了 stub参数
            if (ConfigUtils.isNotEmpty(stub)) {
                Class<?> serviceType = invoker.getInterface();
                if (ConfigUtils.isDefault(stub)) {
                    if (invoker.getUrl().hasParameter(Constants.STUB_KEY)) {  //设置了stub则构造  interfaceStub 
                        stub = serviceType.getName() + "Stub";
                    } else {
                        stub = serviceType.getName() + "Local";   //否则构造 interfeceLocal
                    }
                }
                try {
                    Class<?> stubClass = ReflectUtils.forName(stub);   //生成Stub的Class
                    if (!serviceType.isAssignableFrom(stubClass)) {
                        throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + serviceType.getName());
                    }
                    try {
                        Constructor<?> constructor = ReflectUtils.findConstructor(stubClass, serviceType);  //构建Stub instance
                        proxy = (T) constructor.newInstance(new Object[]{proxy});
                        //export stub service
                        URL url = invoker.getUrl();
                        if (url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT)) {
                            url = url.addParameter(Constants.STUB_EVENT_METHODS_KEY, StringUtils.join(Wrapper.getWrapper(proxy.getClass()).getDeclaredMethodNames(), ","));
                            url = url.addParameter(Constants.IS_SERVER_KEY, Boolean.FALSE.toString());
                            try {
                                export(proxy, (Class) invoker.getInterface(), url);
                            } catch (Exception e) {
                                LOGGER.error("export a stub service error.", e);
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        throw new IllegalStateException("No such constructor \"public " + stubClass.getSimpleName() + "(" + serviceType.getName() + ")\" in stub implementation class " + stubClass.getName(), e);
                    }
                } catch (Throwable t) {
                    LOGGER.error("Failed to create stub implementation class " + stub + " in consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", cause: " + t.getMessage(), t);
                    // ignore
                }
            }
        }
        return proxy;
    }

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
        return proxyFactory.getInvoker(proxy, type, url);
    }

    private <T> Exporter<T> export(T instance, Class<T> type, URL url) {
        return protocol.export(proxyFactory.getInvoker(instance, type, url));
    }
以上分析得出,最终返回至ReferenceConfig 的 ref=createProxy(map) -> return proxyFactory.getProxy(Invoker); 即为 new com.alibaba.dubbo.common.bytecode.proxy0( new InvokerInvocationHandler(invoker) )

DemoService 引用构建完毕
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值