image.png
本节介绍 Dubbo 十层架构中的 Proxy 层。
image.png
- ProxyFactory:代理工厂接口;
- StubProxyFactoryWrapper:代理工厂装饰类(封装了对
stub
和local
的处理逻辑),会在获取ProxyFactory
具体子类时进行 AOP;- AbstractProxyFactory:代理工厂模板类(封装了获取组装接口的功能,用于创建动态代理),提供了模板方法;
- JavassistProxyFactory:基于 Javassist 实现的代理工厂;
- JdkProxyFactory:基于 JDK 动态代理实现的代理工厂;
- AbstractProxyInvoker:最终封装的代理 Invoker,其子类内部发起真正的调用;
- InvokerInvocationHandler:Proxy 发起调用时,会调用该类的 invoke(...),在该 invoke(...) 方法中,默认会调用
MockClusterInvoker
的 invoke(...),之后一路进行调用。
一、代理工厂接口 ProxyFactory
@SPI("javassist")
public interface ProxyFactory {
/**
* 使用端:consumer
*
* 创造一个代理,用于服务引用创建代理
* @param invoker会被proxy调用的第一层Invoker,默认是 MockClusterInvoker
* @return proxy 代理对象
*/
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker) throws RpcException;
/**
* 使用端:provider
*
* 创建一个Invoker,默认是代理Invoker -- AbstractProxyInvoker 的子类对象
* @param <T> 接口 eg. com.alibaba.dubbo.demo.DemoService
* @param proxy ref实例, eg. emoServiceImpl实例
* @param type interface eg. com.alibaba.dubbo.demo.DemoService
* @param url --
* injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?anyhost=true...
* registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider...&export=dubbo://10.213.11.98:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true...
* @return invoker,默认是代理Invoker -- AbstractProxyInvoker 的子类对象
*/
@Adaptive({Constants.PROXY_KEY})
<T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}
二、代理工厂装饰类 StubProxyFactoryWrapper
public class StubProxyFactoryWrapper implements ProxyFactory {
// 真正的ProxyFactory具体子类(JavassistProxyFactory/JdkProxyFactory)
private final ProxyFactory proxyFactory;
// 具有父类SPI接口(ProxyFactory)的单参构造器,所以该类是一个Wrapper类,会在getExtension获取ProxyFactory具体子类时进行aop
public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
}
/**
* 使用端:consumer
*/
@Override
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
// 1. 调用 ProxyFactory 获取代理
T proxy = proxyFactory.getProxy(invoker);
// 2. 如果不是泛化接口,处理 stub 和 local
...
return proxy;
}
/**
* 使用端:provider
*/
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
return proxyFactory.getInvoker(proxy, type, url);
}
}
三、代理工厂模板类 AbstractProxyFactory
public abstract class AbstractProxyFactory implements ProxyFactory {
@Override
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
/**
* 1. 构造接口参数,默认只有 invoker.getInterface()(eg. DemoService), EchoService.class 两个接口
*/
...
Class<?>[] interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class};
...
/**
* 2. 调用子类的实现去创建代理
*/
return getProxy(invoker, interfaces);
}
/**
* 提供给子类的抽象方法
*/
public abstract <T> T getProxy(Invoker<T> invoker, Class<?>[] types);
}
四、JdkProxyFactory
public class JdkProxyFactory extends AbstractProxyFactory {
// 使用端:consumer
@Override
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
// 使用JDK方式创建Java动态代理,创建了动态代理的逻辑处理类 InvokerInvocationHandler,并且传入了 MockClusterInvoker
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));
}
// 使用端:provider
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// 创建真正的Invoker代理
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
// 获取真正的方法Method,proxy=DemoServiceImpl实例
Method method = proxy.getClass().getMethod(methodName, parameterTypes);
// 执行真正的方法
return method.invoke(proxy, arguments);
}
};
}
}
五、JavassistProxyFactory
public class JavassistProxyFactory extends AbstractProxyFactory {
// 使用端:consumer
@Override
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
// 使用 com.alibaba.dubbo.common.bytecode.Proxy 创建代理,创建了动态代理的逻辑处理类 InvokerInvocationHandler,并且传入了 MockClusterInvoker
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
// 使用端:provider
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
// 直接调用wrapper,wrapper底层调用DemoServiceImpl
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
}
首先来看下 consumer 端:
Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker))
这里首先调用 Proxy.getProxy(interfaces)
获取到一个创建代理的工厂类 com.alibaba.dubbo.common.bytecode.Proxy0
,如下:
package com.alibaba.dubbo.common.bytecode;
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.bytecode.Proxy;
import com.alibaba.dubbo.common.bytecode.proxy0;
import java.lang.reflect.InvocationHandler;
public class Proxy0 extends Proxy implements ClassGenerator.DC {
public Object newInstance(InvocationHandler invocationHandler) {
return new proxy0(invocationHandler);
}
}
之后调用了 Proxy0#newInstance
方法,创建了一个 com.alibaba.dubbo.common.bytecode.proxy0
实例,该实例就是最终的 DemoService 的代理对象。
DemoService demoService = (DemoService) context.getBean("demoService");
这里的 demoService 就是上述的 com.alibaba.dubbo.common.bytecode.proxy0
实例。
package com.alibaba.dubbo.common.bytecode;
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.demo.DemoService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class proxy0 implements EchoService, DemoService {
public static Method[] methods;
private InvocationHandler handler;
public String sayHello(String string) {
Object[] arrobject = new Object[]{string};
Object object = this.handler.invoke(this, methods[0], arrobject);
return (String)object;
}
public Object $echo(Object object) {
Object[] arrobject = new Object[]{object};
Object object2 = this.handler.invoke(this, methods[1], arrobject);
return object2;
}
public proxy0() {
}
public proxy0(InvocationHandler invocationHandler) {
this.handler = invocationHandler;
}
}
- proxy0 实现的接口就是 AbstractProxyFactory 中获取的接口;
- 当调用
proxy0#sayHello
时,实际上其内部执行的是InvokerInvocationHandlerr#invoke
,来看一下 InvokerInvocationHandler。
六、代理逻辑处理类 InvokerInvocationHandler
public class InvokerInvocationHandler implements InvocationHandler {
/**
* 第一个被Proxy调用的Invoker,默认为MockClusterInvoker
*/
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...
// 1. 创建请求参数RpcInvocation
// 2. 执行调用
// 3. 对调用结果进行重建recreate():若响应有异常,直接抛异常;否则返回响应
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
}
七、Invoker代理 AbstractProxyInvoker
public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
// 真实对象 ref, eg. DemoServiceImpl
private final T proxy;
// 接口类型,eg. DemoService
private final Class<T> type;
...
public AbstractProxyInvoker(T proxy, Class<T> type, URL url) {
...
this.proxy = proxy;
this.type = type;
...
}
...
/**
* 进行调用
* @param invocation 请求参数
* @return 返回结果
* @throws RpcException
*/
@Override
public Result invoke(Invocation invocation) throws RpcException {
try {
// 1. 调用子类发起请求
// 2. 包装响应为 RpcResult
return new RpcResult(doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()));
} catch (InvocationTargetException e) {
return new RpcResult(e.getTargetException());
} catch (Throwable e) {
throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
// 子类覆写的真正调用的方法
protected abstract Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable;
}
AbstractProxyInvoker
的子类在 JdkProxyFactory#getInvoker(...)
和 JavassistProxyFactory#getInvoker(...)
中进行创建的,来看下JavassistProxyFactory#getInvoker(...)
:
// 使用端:provider
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// wrapper:通过动态生成一个真实的服务提供者(DemoServiceImpl)的wrapper类,来避免反射调用
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass());
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
// 直接调用wrapper,wrapper底层调用DemoServiceImpl
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
再贴下最终生成的 wrapper 类实例(com.alibaba.dubbo.common.bytecode.Wrapper0
)。
package com.alibaba.dubbo.common.bytecode;
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.bytecode.NoSuchMethodException;
import com.alibaba.dubbo.common.bytecode.NoSuchPropertyException;
import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.demo.DemoService;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
public class Wrapper0 extends Wrapper implements ClassGenerator.DC {
...
/**
* @param object 实现类ref,eg. DemoServiceImpl
* @param string 方法名称
* @param arrclass 参数类型
* @param arrobject 参数值
* @return 调用返回值
* @throws java.lang.reflect.InvocationTargetException
*/
public Object invokeMethod(Object object, String string, Class[] arrclass, Object[] arrobject) throws InvocationTargetException {
DemoService demoService;
try {
demoService = (DemoService)object;
} catch (Throwable throwable) {
throw new IllegalArgumentException(throwable);
}
try {
if ("sayHello".equals(string) && arrclass.length == 1) {
return demoService.sayHello((String)arrobject[0]);
}
} catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
throw new NoSuchMethodException(new StringBuffer().append("Not found method \"").append(string).append("\" in class com.alibaba.dubbo.demo.DemoService.").toString());
}
...
}
网友评论