在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);
}
};
}