RpcContext

本文详细介绍了 Dubbo 中的 RpcContext 类及其 ThreadLocal 的使用方式,并通过示例展示了如何设置调用方式为异步,以及如何在 DubboInvoker 中实现异步调用并设置 Future 对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RpcContext内部有一个ThreadLocal变量,它是作为ThreadLocalMap的key,表明每个线程有一个RpcContext。

public class RpcContext {
    private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() {
        @Override
        protected RpcContext initialValue() {
            return new RpcContext();
        }
    };

    //如果get在set之前,则get会返回initialValue()创建的对象
    public static RpcContext getContext() {
        return LOCAL.get();
    }
}

1. RpcContext的一种用法是:存放Future。Future封装了consumer的请求和响应,发送请求时会创建Future对象,此时响应是null,而DubboClientHandler线程会设置响应值。

设置调用方式为异步:

<dubbo:service interface="com.zhang.HelloService" ref="helloServiceImpl" protocol="dubbo">
    <dubbo:method name="sayHello" retries="0" async="true"></dubbo:method>
</dubbo:service>

RpcContext设置Future:

//DubboInvoker
protected Result doInvoke(final Invocation invocation) throws Throwable {
    RpcInvocation inv = (RpcInvocation) invocation;
    final String methodName = RpcUtils.getMethodName(invocation);
    inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
    inv.setAttachment(Constants.VERSION_KEY, version);
    
    ExchangeClient currentClient;
    if (clients.length == 1) {
        currentClient = clients[0];
    } else {
        currentClient = clients[index.getAndIncrement() % clients.length];
    }
    try {
        boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
        boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
        int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY,
Constants.DEFAULT_TIMEOUT);
if (isOneway) { boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false); currentClient.send(inv, isSent); RpcContext.getContext().setFuture(null); return new RpcResult(); } else if (isAsync) { //异步调用,设置Future ResponseFuture future = currentClient.request(inv, timeout) ; RpcContext.getContext().setFuture(new FutureAdapter<Object>(future)); return new RpcResult(); } else { RpcContext.getContext().setFuture(null); return (Result) currentClient.request(inv, timeout).get(); } } catch (TimeoutException e) { } catch (RemotingException e) { } }

调用时直接返回:

HelloService helloService = (HelloService) appCtx.getBean("hello");
//返回null
String str = helloService.sayHello();

Future<String> future = RpcContext.getContext().getFuture();
//阻塞获取结果
String str2 = future.get();

 

转载于:https://www.cnblogs.com/allenwas3/p/8384206.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值