本篇幅分析Dubbo创建代理对象流程,我们在刚开始分析服务引用章节,提到了最终Dubbo会根据invoker使用proxyFactory创建代理对象,本篇幅主要目的就是为了分析proxyFactory.getProxy(invoker);
ReferenceConfig.createProxy(Map<String,String> map)
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
private T createProxy(Map<String, String> map) {
URL tmpUrl = new URL("temp", "localhost", 0, map);
final boolean isJvmRefer;
//本地jvm引用配置
if (isInjvm() == null) {
// url 配置被指定,则不做本地引用
if (url != null && url.length() > 0) {
isJvmRefer = false;
// 根据 url 的协议、scope 以及 injvm 等参数检测是否需要本地引用
// 比如如果用户显式配置了 scope=local,此时 isInjvmRefer 返回 true
} else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
isJvmRefer = true;
} else {
isJvmRefer = false;
}
} else {
//injvm配置
isJvmRefer = isInjvm().booleanValue();
}
//本地jvm引用
if (isJvmRefer) {
//new一个本地引用url injvm协议的并将Map的参数添加到URL对象中
URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
//创建invoker实例
invoker = refprotocol.refer(interfaceClass, url);
if (logger.isInfoEnabled()) {
logger.info("Using injvm service " + interfaceClass.getName());
}
} else {
//url不为空,指定的URL可能是对点对直连地址,也可能是注册中心URL
if (url != null && url.length() > 0) {
//按照;切分url字符串(因为url可能配置多个!!!)
String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
if (us != null && us.length > 0) {
for (String u : us) {
//将字符串转换为URL对象
URL url = URL.valueOf(u);
//设置接口全限定名称的url
if (url.getPath() == null || url.getPath().length() == 0) {
url = url.setPath(interfaceName);
}
//检测 url 协议是否为 registry,若是,表明用户想使用指定的注册中心
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
//将map变成?key=value&key2=value2这种的,然后作为refer属性的值添加到url中
urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
} else {
//合并 url,移除服务提供者的一些配置(这些配置来源于用户配置的url属性)
//比如线程池相关配置。并保留服务提供者的部分配置,比如版本,group,时间戳等
//后将合并后的配置设置为 url 查询字符串中。
urls.add(ClusterUtils.mergeUrl(url, map));
}
}
}
} else {
//加载注册中心url
//registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=echo-consumer&dubbo=2.0.2&
// pid=16304®istry=zookeeper×tamp=1573441590938
List<URL> us = loadRegistries(false);
if (us != null && !us.isEmpty()) {
for (URL u : us) {
//加载监控中心配置,赞不关心
URL monitorUrl = loadMonitor(u);
if (monitorUrl != null) {
map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
}
//添加refer参数到url中
urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
}
}
if (urls.isEmpty()) {
throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
}
}
//单个注册中心或服务提供者(服务直连,下同)
if (urls.size() == 1) {
//调用RegistryProtocol的refer方法创建invoker
invoker = refprotocol.refer(interfaceClass, urls.get(0));
//多个注册中心或多个服务提供者,或者两中情况都存在
} else {
List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
URL registryURL = null;
//获取所有Invoker
for (URL url : urls) {
invokers.add(refprotocol.refer(interfaceClass, url));
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
registryURL = url; // use last registry url
}
}
//如果注册中心的url是没问题的;使用AvaliableCluster
if (registryURL != null) { // registry url is available
// use AvailableCluster only when register's cluster is available
URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
invoker = cluster.join(new StaticDirectory(u, invokers));
} else { // not a registry url
invoker = cluster.join(new StaticDirectory(invokers));
}
}
}
Boolean c = check;
if (c == null && consumer != null) {
c = consumer.isCheck();
}
if (c == null) {
c = true; // default true
}
//如果要检查提供者是否存在但是invoker不可用,抛出异常
if (c && !invoker.isAvailable()) {
// make it possible for consumer to retry later if provider is temporarily unavailable
initialized = false;
throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
}
if (logger.isInfoEnabled()) {
logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
}
// create service proxy
// 生成代理类
return (T) proxyFactory.getProxy(invoker);
}
代码最后一行,会通过ReferenceConfig的成员变量proxyFactory根据得到的Cluster Invoker对象创建代理对象,关于proxyFactory初始化
private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
根据dubbo的spi机制可知proxyFactory的类型为ProxyFactory$Adaptive
public class ProxyFactory$Adaptive implements com.alibaba.dubbo.rpc.ProxyFactory {
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 {
if (arg2 == null) throw new IllegalArgumentException("url == null");
com.alibaba.dubbo.common.URL url = arg2;
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
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);
}
public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0, boolean arg1) throws com.alibaba.dubbo.rpc.RpcException {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null)
throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
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, arg1);
}
public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null)
throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = url.getParameter("proxy", "javassist");
if (extName == null)
throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
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);
}
}
由于ProxyFactory有包装类StubProxyFactoryWrapper所以最终获取得到的ProxyFactory的实例是StubProxyFactoryWrapper,它包装了JavassistProxyFactory对象。有图为证
ProxyFactory
- ProxyFactory:创建代理和invoker抽象接口
@SPI("javassist")
public interface ProxyFactory {
/**
* 创建代理
*
* @param invoker
* @return proxy
*/
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker) throws RpcException;
/**
* 创建代理
*
* @param invoker
* @return proxy
*/
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;
/**
* 创建Invoker
*
* @param <T>
* @param proxy
* @param type
* @param url
* @return invoker
*/
@Adaptive({Constants.PROXY_KEY})
<T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}
- AbstractProxyFactory:抽象的ProxyFactory的实现,帮我们实现了获取代理对象之前的准备工作,即创建代理对象需要的接口数组处理
- JavassistProxyFactory:基于Javassist技术创建代理对象的ProxyFactory的实现
- JdkProxyFactory:基于jdk动态代理创建代理对象的ProxyFactory的实现
- StubProxyFactoryWrapper:实现了ProxyFactory接口,内部持有一个JdkProxyFactory或者JavassistProxyFactory对象,主要是代理对象的本地存根实现,关于本地存根参考http://dubbo.apache.org/zh-cn/docs/user/demos/local-stub.html,
StubProxyFactoryWrapper.getProxy(Invoker<T> invoker)
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
//委托JavassistProxyFactory或者JdkProxyFactory创建代理对象
T proxy = proxyFactory.getProxy(invoker);
//
if (GenericService.class != invoker.getInterface()) {
String stub = invoker.getUrl().getParameter(Constants.STUB_KEY, invoker.getUrl().getParameter(Constants.LOCAL_KEY));
if (ConfigUtils.isNotEmpty(stub)) {
//获取接口类型
Class<?> serviceType = invoker.getInterface();
//本地存根配置判断
if (ConfigUtils.isDefault(stub)) {
if (invoker.getUrl().hasParameter(Constants.STUB_KEY)) {
stub = serviceType.getName() + "Stub";
} else {
stub = serviceType.getName() + "Local";
}
}
try {
//加载本地存根类
Class<?> stubClass = ReflectUtils.forName(stub);
//判断本地存根类是否实现了serviceType,没有抛出异常
if (!serviceType.isAssignableFrom(stubClass)) {
throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + serviceType.getName());
}
try {
//查找本地存根类是否有 serviceType的构造函数
Constructor<?> constructor = ReflectUtils.findConstructor(stubClass, serviceType);
//有的话使用proxy对象创建stub对象返回
proxy = (T) constructor.newInstance(new Object[]{proxy});
//如果dubbo.stub.event 配置为true,export
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;
}
上述代码的逻辑首先会,委托javassistProxyFactory或者jdkProxyFactory创建代理对象,然后判断此次调用invoker的url中的本地存根配置,如果需要创建本地存根,首先将调用的serviceType拼接Local或者Stub(比如最终拼接为HelloServiceStub)这种,然后加载本地存根类,然后判断本地存根类的构造函数是否合理,即本地存根类的构造函数必须以ServiceType构造,然后根据创建的代理对象proxy创建本地存根类的对象,最后判断是否需要export,需要export,就进行一次export好了。关于怎么使用本地存根不是本文重点内容,如有兴趣可以参考https://github.com/SpringStudent/dubbo/tree/master/study-dubbo/src/main/java/com/alibaba/dubbo/study/day04下的代码。
AbstractProxyFactory.getProxy(Invoker<T> invoker, boolean generic)
@Override
public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
//接口数组
Class<?>[] interfaces = null;
//获取接口列表
String config = invoker.getUrl().getParameter("interfaces");
if (config != null && config.length() > 0) {
//使用,切分接口列表
String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
if (types != null && types.length > 0) {
//设置服务接口类和 EchoService.class 到 interfaces 中
interfaces = new Class<?>[types.length + 2];
interfaces[0] = invoker.getInterface();
interfaces[1] = EchoService.class;
//加载接口类放到interfaces[]数组中
for (int i = 0; i < types.length; i++) {
interfaces[i + 1] = ReflectUtils.forName(types[i]);
}
}
}
//如果接口为null,放入下面这两个接口
if (interfaces == null) {
interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class};
}
//为http和hessian调用添加支持 添加了GenericService
if (!invoker.getInterface().equals(GenericService.class) && generic) {
int len = interfaces.length;
Class<?>[] temp = interfaces;
interfaces = new Class<?>[len + 1];
System.arraycopy(temp, 0, interfaces, 0, len);
interfaces[len] = GenericService.class;
}
return getProxy(invoker, interfaces);
}
上面大段代码都是用来获取 interfaces 数组的,我们继续往下看getProxy(invoker,interfaces)的代码实现。
JdkProxyFactory.getProxy(Invoker<T> invoker, Class<?>[] interfaces)
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));
}
jdk动态代理创建代理对象,固定模板,我们重点分析javassistProxyFactory的实现
JavassistProxyFactory.getProxy(Invoker<T> invoker, Class<?>[] interfaces)
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
通过Proxy.getProxy方法获取Proxy对象,然后调用Proxy对象的newInstance方法创建代理对象
Proxy.getProxy(Class<?>... ics)
public static Proxy getProxy(Class<?>... ics) {
return getProxy(ClassHelper.getClassLoader(Proxy.class), ics);
}
Proxy.getProxy(ClassLoader cl, Class<?>... ics)
/**
* 获取proxy对象
*
* @param cl class loader.
* @param ics interface class array.
* @return Proxy instance.
*/
public static Proxy getProxy(ClassLoader cl, Class<?>... ics) {
//如果接口数量超过了65535抛出异常,说吧你是不是学的jdk的可重入锁的源码!
if (ics.length > 65535)
throw new IllegalArgumentException("interface limit exceeded");
StringBuilder sb = new StringBuilder();
//遍历接口列表
for (int i = 0; i < ics.length; i++) {
String itf = ics[i].getName();
//竟然不是接口抛出异常
if (!ics[i].isInterface())
throw new RuntimeException(itf + " is not a interface.");
//加载接口类
Class<?> tmp = null;
try {
tmp = Class.forName(itf, false, cl);
} catch (ClassNotFoundException e) {
}
//不是同一个类加载器加载的clss抛出异常
if (tmp != ics[i])
throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
sb.append(itf).append(';');
}
// use interface class name list as key.
// 拼接所有的接口名称后 toString作为key
String key = sb.toString();
// get cache by class loader.
Map<String, Object> cache;
synchronized (ProxyCacheMap) {
// key 为classLoader value为cache
cache = ProxyCacheMap.get(cl);
if (cache == null) {
cache = new HashMap<String, Object>();
ProxyCacheMap.put(cl, cache);
}
}
Proxy proxy = null;
//加锁
synchronized (cache) {
do {
//从缓存中获取 Reference<Proxy> 实例
//取到了调用get方法返回proxy
Object value = cache.get(key);
if (value instanceof Reference<?>) {
proxy = (Proxy) ((Reference<?>) value).get();
if (proxy != null)
return proxy;
}
//并发控制,保证只有一个线程可以后续操作
if (value == PendingGenerationMarker) {
try {
cache.wait();
} catch (InterruptedException e) {
}
} else {
cache.put(key, PendingGenerationMarker);
break;
}
}
while (true);
}
//id自增器
long id = PROXY_CLASS_COUNTER.getAndIncrement();
String pkg = null;
//代理类
ClassGenerator ccp = null;
//Proxy实现类创建ccp的对象
ClassGenerator ccm = null;
try {
// 使用当前ClassLoader创建 ClassGenerator 对象,
ccp = ClassGenerator.newInstance(cl);
Set<String> worked = new HashSet<String>();
List<Method> methods = new ArrayList<Method>();
for (int i = 0; i < ics.length; i++) {
//如果ics不是public的接口,则需要判断接口是否同包
if (!Modifier.isPublic(ics[i].getModifiers())) {
//获取包名称
String npkg = ics[i].getPackage().getName();
if (pkg == null) {
//赋值pkg
pkg = npkg;
} else {
if (!pkg.equals(npkg))
throw new IllegalArgumentException("non-public interfaces from different packages");
}
}
//添加接口到ccp中
ccp.addInterface(ics[i]);
//遍历接口的方法
for (Method method : ics[i].getMethods()) {
//获取方法签名
String desc = ReflectUtils.getDesc(method);
// 如果方法描述字符串已在 worked 中,则忽略。考虑这种情况,
// A 接口和 B 接口中包含一个完全相同的方法
if (worked.contains(desc))
continue;
worked.add(desc);
int ix = methods.size();
//获取方法返回值
Class<?> rt = method.getReturnType();
//获取方法的参数列表
Class<?>[] pts = method.getParameterTypes();
// 生成 Object[] args = new Object[1...N]
StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
for (int j = 0; j < pts.length; j++)
// 生成 args[1...N] = ($w)$1...N;
code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";");
// 生成 InvokerHandler 接口的 invoker 方法调用语句,如下:
// 生成 InvokerHandler 接口的 invoker 方法调用语句,如下
code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");
// 返回值不为 void
if (!Void.TYPE.equals(rt))
// 生成返回语句,形如 return (java.lang.String) ret;
code.append(" return ").append(asArgument(rt, "ret")).append(";");
methods.add(method);
// 添加方法名、访问控制符、参数列表、方法代码等信息到 ClassGenerator 中
// 说白了就是拼接成为public Integer getName(Integer arg0){...}这种代码字符串
ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
}
}
if (pkg == null)
pkg = PACKAGE_NAME;
// create ProxyInstance class.
// 构建接口代理类名称:pkg + ".proxy" + id,比如 org.apache.dubbo.proxy0
String pcn = pkg + ".proxy" + id;
//设置className
ccp.setClassName(pcn);
//添加静态成员变量
ccp.addField("public static java.lang.reflect.Method[] methods;");
//生成 private java.lang.reflect.InvocationHandler handler;
ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
// 为接口代理类添加带有 InvocationHandler 参数的构造方法,比如:
// porxy0(java.lang.reflect.InvocationHandler arg0) {
// handler=$1;
// }
ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
//添加默认构造方法
ccp.addDefaultConstructor();
//生成接口代理类的对象
Class<?> clazz = ccp.toClass();
//赋值methods属性
clazz.getField("methods").set(null, methods.toArray(new Method[0]));
// create Proxy class.
String fcn = Proxy.class.getName() + id;
//构建 Proxy 子类名称,比如 Proxy1,Proxy2 等
ccm = ClassGenerator.newInstance(cl);
ccm.setClassName(fcn);
ccm.addDefaultConstructor();
ccm.setSuperClass(Proxy.class);
// 为 Proxy 的抽象方法 newInstance 生成实现代码,形如:
// public Object newInstance(java.lang.reflect.InvocationHandler h) {
// return new org.apache.dubbo.proxy0($1);
// }
ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
// 通过反射创建 Proxy 实例
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.首先是接口数组的判断逻辑,如果不是接口,或者接口不存在抛出异常
- 2.由classLoader为key取得 一个cache Map<String,Object> key为接口数组拼接的字符串(例如"HelloService;EchoService"),Value为Proxy对象,如果没有找到classLoader的cache,则创建一个
- 3.根据key--接口数组拼接的字符串(例如"HelloService;EchoService")从cache中获取Proxy的实例获取到了直接返回,获取不到,循环加锁直到成功
- 4.使用javaassist创建加载代理类例如proxy0,和Proxy类的实现类Proxy0。其中Proxy0实现了Proxy类,用于创建proxy0对象
proxy0.java
一般的proxy0的代码类似:
package org.apache.dubbo.common.bytecode;
public class proxy0 implements org.apache.dubbo.demo.DemoService {
public static java.lang.reflect.Method[] methods;
private java.lang.reflect.InvocationHandler handler;
public proxy0() {
}
public proxy0(java.lang.reflect.InvocationHandler arg0) {
handler = $1;
}
public java.lang.String sayHello(java.lang.String arg0) {
Object[] args = new Object[1];
args[0] = ($w) $1;
Object ret = handler.invoke(this, methods[0], args);
return (java.lang.String) ret;
}
}
InvokerInvocationHandler
该类实现了jdk的接口InvocationHandler,主要用户代理对象的方法调用的执行,服务消费方的方法调用,最后都是通过该类的invoke实现的。
public class InvokerInvocationHandler implements InvocationHandler {
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}
@Override
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();
}
}
关于调用流程我们放到后面分析~