本篇次要介绍 dubbo 的隐式传参如何应用以及其原理。通过隐式传参,咱们能够在不改变接口的状况下传递一些额定的数据给服务端来实现一些特定的性能。
概念
什么是隐式传参,咱们看名字根本就可能猜出来,暗地里把参数传给服务提供者。先思考一下咱们平时是怎么应用 dubbo 的(如何搭建并进行调用),个别都是服务提供方会定义好接口而后交给客户端来引入应用,也就是一开始客户端就晓得服务端有哪些接口以及其定义是怎么样的。而隐式传参则是客户端本人定义的参数,客户端和服务端要约定好想要传哪些参数,客户端传了之后服务端能够取出来做一些解决。
更艰深的说:
当初华山派招弟子,有心法系和剑系两项能够抉择,你进入华山派的话失常只能练其中一项,然而你能够在抉择任何一项之后本人偷偷带一本秘籍过来修炼,这偷偷带过来的货色就是隐式传参。
应用
上面用一个例子来阐明一下如何进行应用,本例子要达到的目标是日志惟一追踪号传递,具体的细节在这篇曾经讲过 dubbo Filter 应用,这里就讲一下其中波及到的隐式传参怎么做的。在那篇例子中,咱们写到一段代码:
// 对于服务提供端,Activate 改为 Constants.PROVIDER
@Activate(group = {Constants.CONSUMER})
public class UniqIdTraceFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 此处逻辑能够自定义
String traceId = UUID.randomUUID().toString().replace("-", "");
RpcContext.getContext().setAttachment("traceId", traceId);
return invoker.invoke(invocation);
}
}
这段代码里 RpcContext.getContext().setAttachment("traceId", traceId);
这句话就是隐式传参的应用。咱们看下 setAttachment
办法的定义:
这里能够看进去其中就是一个 map,key 就是咱们要传递给服务端的参数的键,value 就是服务端将会获取到的值,具体如何应用你能够在服务端自定义。这里传递 traceId 给服务端之后,服务端就能够通过RpcContext.getContext().getAttachment("traceId")
来获取到日志惟一追踪号。
原理
借着应用来讲一下隐式传参的原理。基于下面的例子,咱们晓得应用隐式传参很简略:
RpcContext.getContext().setAttachment("traceId", traceId)
咱们看下 dubbo 是如何做到从客户端传递到服务端的。在下面的例子中,咱们在客户端申请过来的时候,通过了 Filter,在 Filter 中退出了我本人的定义的隐式传参的内容 traceId,在 org.apache.dubbo.rpc.protocol.AbstractInvoker#invoke
的逻辑中会将咱们 RpcContext 中的参数传递到 RpcInvocation 中,如图:
这个 RpcInvocation 就是客户端申请服务端带过来的是数据。在服务端接管到的申请内容中,咱们能够看到 traceId,其余的是 dubbo 本人须要解决的参数:
在咱们讲 dubbo Filter 应用 的时候讲到过 dubbo 有一些本人内置的 Filter,其中有一个 Filter 叫做 ContextFilter,该 Filter 就会将收到的 RpcInvocation 中的参数设置到 RpcContext 中去:
大略的实现原理就是如此,其实也非常简单。
总结
本篇曾经对隐式传参讲得十分分明了,这里的案例是用的 Filter 的形式设置和获取参数,大家也能够在其余代码逻辑下来传递和获取,如果对于原理篇还是不了解,能够本人参照原理篇说的调试下。