在前面几篇文章中,我们分析了consumer端的代理生成过程。创建完成后,应用就可以进行调用了,调用的代码如下:
// 代理类中的sayHello方法
public String sayHello(String paramString) {
// 将调用时的参数传入arrayOfObject中
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] = paramString;
// methods[0]表示的就是sayHello, handler的实现为com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler
Object localObject = this.handler.invoke(this, methods[0], arrayOfObject);
return (String)localObject;
}
// InvokerInvocationHandler的invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object中的方法不用远程调用
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
if (method.getDeclaringClass() == Object.class) {
return method.invoke(invoker, args);
}
if ("toString".equals(methodName) && parameterTypes.length == 0) {
return invoker.toString();
}
if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
return invoker.hashCode();
}
if ("equals".equals(methodName) && parameterTypes.length == 1) {
return invoker.equals(args[0]);
}
// 将方法和参数封装成RpcInvocation后调用,recreate方法主要是在调用时如果发生异常则抛出异常,否则正常返回
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
Invocation的主要作用是将(远程)方法调用时需要的信息+Invoker封装起来, 这些信息包括:方法名、参数类型、参数值、附加信息。结合前一篇Invoker创建流程,我们知道此处的invoker为com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker,对应的invoke方法:
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
// 查询mock值,查询顺序methodName[sayHello].mock -> mock -> default.mock, 默认为false,即不进行mock
String value = directory.getUrl().getMethodParameter(invocation.