Dubbo 中的 RpcContext 源码学习以及作用分析
/RpcContext中的注释是:
* 注意:RpcContext是一个临时状态记录器,当接收到RPC请求,或发起RPC请求时,RpcContext的状态都会变化。
* 比如:A调B,B再调C,则B机器上,在B调C之前,RpcContext记录的是A调B的信息,在B调C之后,RpcContext记录的是B调C的信息。
*
* @see com.alibaba.dubbo.rpc.filter.ContextFilter
发现首先初始化了一个 private static final ThreadLocal<RpcContext> LOCAL,里面重写了ThreadLocal的initialValue()函数,就是新建了一个RpcContext。
每一个变量里对应了这么多变量:
private Future<?> future;
private List<URL> urls;
private URL url;
private String methodName;
private Class<?>[] parameterTypes;
private Object[] arguments;
private InetSocketAddress localAddress;
private InetSocketAddress remoteAddress;
private final Map<String, String> attachments = new HashMap<String, String>();
private final Map<String, Object> values = new HashMap<String, Object>();
我们首先对RpcContext Find Usages ,发现整个工程中有二三十处引用,当然引用,无非就是调用上面的值,或者设置上面的值。
比如DubboInvoker中的doInvoke()函数,提取当前的ExchangeClient设置Future(),当然ExchangeClient就是对应的provider和consumer之间的链接信息,如果a调b,b调c,因为这是一个线程,那么此时的future将来就会返回b调c的内容。而不是a调b的内容。
这个类的作用就是记录当前线程,最近一次调用的一些变量。
比如在FutureFilter中的asyncCallback中会发现,首先得到了RpcContext.getContext.getFuture()的Future<?> f,然后对返回的结果进行日志输出,比如invalid result type,如果没有异常,我们将会调用fireReturnCallback(Invoker,Invocation,Object result),这个函数,就是根据invoker的url,出发成功后必须调用的函数。从里面的java反射写法既可以看出。
final Method onReturnMethod = (Method)StaticContext.getSystemContext().get(StaticContext.getKey(
invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_METHOD_KEY));
final Object onReturnInst = StaticContext.getSystemContext().get(StaticContext.getKey(
invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_INSTANCE_KEY));
onReturnMethod.invoke(onReturnInst, params);
可见设计的还是不错的。学习了ThreadLocal在大型工程中的使用场景。