(十五)RpcContext对象
来源:互联网 发布:淘宝大马士革刀真假 编辑:程序博客网 时间:2024/06/05 05:19
比如现在消费者A调用提供者B,
在RPC调用之前,消费者可以调用RpcContext.getContext().setAttachment(key, value);
设置一些隐含参数,然后在提供者B可以通过RpcContext.getContext().getAttachment(key);拿到key的value。
如果B又接着调用C,那么RpcContext则会放着B的调用C的参数,而之前A调用B的参数已经是不存在的。
直接看下RpcContext的源码。
看出来RpcContext对象是绑定在线程临时变量LOCAL上,所以可以通过线程临时变量来获取到RpcContext的相关参数值。
下面看看RPC调用时是怎么将RpcContext上的参数传输给提供者的,类com.alibaba.dubbo.rpc.protocol.AbstractInvoker<T>的一段源码:
在调用提供者之前,在源码“41处”,会获取当前线程临时变量里的RpcContext对象,再将RpcContext对象里的参数设置到Invocation对象,最后调用doInvoke(Invocation invocation)方法,就会发送参数给提供者。
在RPC调用之前,消费者可以调用RpcContext.getContext().setAttachment(key, value);
设置一些隐含参数,然后在提供者B可以通过RpcContext.getContext().getAttachment(key);拿到key的value。
如果B又接着调用C,那么RpcContext则会放着B的调用C的参数,而之前A调用B的参数已经是不存在的。
直接看下RpcContext的源码。
public class RpcContext { private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() { @Override protected RpcContext initialValue() { return new RpcContext(); } }; /** * get context. * * @return context */ public static RpcContext getContext() { return LOCAL.get(); } //省略其他属性 private Future<?> future; private final Map<String, String> attachments = new HashMap<String, String>(); /** * get attachment. * * @param key * @return attachment */ public String getAttachment(String key) { return attachments.get(key); } /** * set attachment. * * @param key * @param value * @return context */ public RpcContext setAttachment(String key, String value) { if (value == null) { attachments.remove(key); } else { attachments.put(key, value); } return this; }
看出来RpcContext对象是绑定在线程临时变量LOCAL上,所以可以通过线程临时变量来获取到RpcContext的相关参数值。
下面看看RPC调用时是怎么将RpcContext上的参数传输给提供者的,类com.alibaba.dubbo.rpc.protocol.AbstractInvoker<T>的一段源码:
public Result invoke(Invocation inv) throws RpcException { if(destroyed) { throw new RpcException("Rpc invoker for service " + this + " on consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + " is DESTROYED, can not be invoked any more!"); } RpcInvocation invocation = (RpcInvocation) inv; invocation.setInvoker(this); if (attachment != null && attachment.size() > 0) { invocation.addAttachmentsIfAbsent(attachment); } Map<String, String> context = RpcContext.getContext().getAttachments(); //41处 if (context != null) { invocation.addAttachmentsIfAbsent(context); } if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)){ invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString()); } RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation); try { return doInvoke(invocation); } catch (InvocationTargetException e) { // biz exception Throwable te = e.getTargetException(); if (te == null) { return new RpcResult(e); } else { if (te instanceof RpcException) { ((RpcException) te).setCode(RpcException.BIZ_EXCEPTION); } return new RpcResult(te); } } catch (RpcException e) { if (e.isBiz()) { return new RpcResult(e); } else { throw e; } } catch (Throwable e) { return new RpcResult(e); }}protected abstract Result doInvoke(Invocation invocation) throws Throwable;
在调用提供者之前,在源码“41处”,会获取当前线程临时变量里的RpcContext对象,再将RpcContext对象里的参数设置到Invocation对象,最后调用doInvoke(Invocation invocation)方法,就会发送参数给提供者。
阅读全文
0 0
- (十五)RpcContext对象
- dubbo的RpcContext隐式传参
- iOS入门(十五)类和对象
- javascript学习(十五)— 创建对象
- 【深入PHP 面向对象】读书笔记(十五)
- (十五)面向对象程序设计
- javascript面向对象(十五)
- JavaScript Date(日期)对象(二十五)
- 49. 面向对象的LotusScript(十五)之Log4Dom下
- PHP学习(十五)--PHP面向对象的程序设计
- Android产品研发(十五)-->内存对象序列化
- Bootstrap 学习之(十五)------ 媒体对象,well
- Android产品研发(十五)-->内存对象序列化
- Kotlin语法(十五)-对象表达式和声明
- javascript学习(十五)内建对象之RegExp
- java学习 十五、面向对象
- 我的php学习笔记(十五)php的面向对象开发(二)
- javascript基础(DOM对象概述,事件,文档加载)(二十五)
- Unity3D 设计模式---工厂模式
- hdu6103 Krinriki(尺取法)
- Tensorflow实战之用softmax Regression识别手写数字
- 关于全栈
- android APK更新原理以及代码实现
- (十五)RpcContext对象
- Repair the Wall
- markdown help
- POJ-2342 Anniversary party(没有上司的晚会) 树状动归
- phpStorm快捷键
- 输入边框&原型设计
- sqlite3_prepare_v2返回26错误码的解决
- 后端往前段传递参数,大部分人都清楚,无非就是发起ajax请求获取后端值,然后通过js写入html相应位置即可。但是前段html页面之间,怎么传递参数呢?
- 配置openresty使用lua并发请求API