引言
我們知道Dubbo消費端引用服務(wù)的時候是根據(jù)本地接口為我們生成代理類,對消費端而言不需要關(guān)心具體的實現(xiàn),代理類幫我們處理底層通信的問題。
ReferenceConfig<IUserService> reference = newReferenceConfig<IUserService>();
reference.setApplication(application);
reference.setRegistry(registry); // 多個注冊中心可以用setRegistries()
reference.setInterface(IUserService.class);
reference.setVersion("1.0.0");
//此時的userService只是IUserService的一個代理類
IUserService userService = reference.get();
代理類反編譯
public class Proxy0 extends Proxy implements DC {
public Object newInstance(InvocationHandler var1) {
return new proxy0(var1);
}
public Proxy0() {
}
}
package com.alibaba.dubbo.common.bytecode;
import com.alibaba.dubbo.common.bytecode.ClassGenerator.DC;
import com.alibaba.dubbo.demo.service.IUserService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
public class proxy0 implements DC, IUserService, EchoService {
public static Method[] methods;
private InvocationHandler handler;
public List findAllUserList() {
Object[] var1 = new Object[0];
Object var2 = this.handler.invoke(this, methods[0], var1);
return (List)var2;
}
public String findPasswd(String var1) {
Object[] var2 = new Object[]{var1};
Object var3 = this.handler.invoke(this, methods[1], var2);
return (String)var3;
}
public void updateUserById(Integer var1) {
Object[] var2 = new Object[]{var1};
this.handler.invoke(this, methods[2], var2);
}
public Object $echo(Object var1) {
Object[] var2 = new Object[]{var1};
Object var3 = this.handler.invoke(this, methods[3], var2);
return (Object)var3;
}
public proxy0() {
}
public proxy0(InvocationHandler var1) {
this.handler = var1;
}
}
從代碼中可知,具體的方法都是由handler.invoke()
來執(zhí)行的,而且該代理類實現(xiàn)了IUserService接口.我們來看一下JavassistProxyFactory:
public class JavassistProxyFactory extends AbstractProxyFactory {
@SuppressWarnings("unchecked")
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// TODO 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);
}
};
}
}
從代碼中可知,newInstance()
方法里包裝了一個InvokerInvocationHandler()
對象仿荆。
public class InvokerInvocationHandler implements InvocationHandler {
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler){
this.invoker = handler;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
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]);
}
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
}
具體的邏輯最終交給了Invoker來執(zhí)行厅贪。