From 28f872780f02678a703a43b6e407389e95da5942 Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Sat, 14 Apr 2018 02:24:44 +0800 Subject: [PATCH] filter --- .../java/com/alibaba/dubbo/rpc/Filter.java | 2 +- .../com/alibaba/dubbo/rpc/RpcContext.java | 32 ++++++++++++++++--- .../com/alibaba/dubbo/rpc/RpcInvocation.java | 9 ++++-- .../dubbo/rpc/filter/ClassLoaderFilter.java | 9 ++++++ .../rpc/filter/ConsumerContextFilter.java | 11 +++++-- .../dubbo/rpc/filter/ContextFilter.java | 17 +++++++--- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/Filter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/Filter.java index f1663148b..6ab2e3ae3 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/Filter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/Filter.java @@ -39,7 +39,7 @@ public interface Filter { * @param invoker service * @param invocation invocation. * @return invoke result. - * @throws RpcException + * @throws RpcException 发生 RpcException 异常 * @see com.alibaba.dubbo.rpc.Invoker#invoke(Invocation) */ Result invoke(Invoker invoker, Invocation invocation) throws RpcException; diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java index 78c6afbbd..845805bbe 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java @@ -56,23 +56,34 @@ import java.util.concurrent.TimeoutException; */ public class RpcContext { + /** + * RpcContext 线程变量 + */ private static final ThreadLocal LOCAL = new ThreadLocal() { + @Override protected RpcContext initialValue() { return new RpcContext(); } + }; + /** + * 隐式参数集合 + */ private final Map attachments = new HashMap(); + // 实际未使用 private final Map values = new HashMap(); /** * 异步调用 Future */ private Future future; - + /** + * 可调用服务的 URL 对象集合 + */ private List urls; /** - * URL 对象 + * 调用服务的 URL 对象 */ private URL url; /** @@ -95,16 +106,27 @@ public class RpcContext { * 服务提供者地址 */ private InetSocketAddress remoteAddress; - @Deprecated + + @Deprecated // DUBBO-325 废弃的,使用 urls 属性替代 private List> invokers; - @Deprecated + @Deprecated // DUBBO-325 废弃的,使用 url 属性替代 private Invoker invoker; - @Deprecated + @Deprecated // DUBBO-325 废弃的,使用 methodName、parameterTypes、arguments 属性替代 private Invocation invocation; // now we don't use the 'values' map to hold these objects // we want these objects to be as generic as possible + /** + * 请求 + * + * 例如,在 RestProtocol + */ private Object request; + /** + * 响应 + * + * 例如,在 RestProtocol + */ private Object response; protected RpcContext() { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java index 0b11323db..4d35d85b8 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java @@ -50,8 +50,12 @@ public class RpcInvocation implements Invocation, Serializable { * 隐式参数集合 */ private Map attachments; - - private transient Invoker invoker; // TODO 芋艿,transient + /** + * Invoker 对象 + * + * 不序列化 + */ + private transient Invoker invoker; public RpcInvocation() { } @@ -120,6 +124,7 @@ public class RpcInvocation implements Invocation, Serializable { this.invoker = invoker; } + @Override public Invoker getInvoker() { return invoker; } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ClassLoaderFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ClassLoaderFilter.java index 624a1f5ec..096f7b35f 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ClassLoaderFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ClassLoaderFilter.java @@ -27,16 +27,25 @@ import com.alibaba.dubbo.rpc.RpcException; /** * ClassLoaderInvokerFilter * + * 类加载器切换过滤器 + * + * https://github.com/apache/incubator-dubbo/issues/1406 + * https://github.com/apache/incubator-dubbo/issues/178 */ @Activate(group = Constants.PROVIDER, order = -30000) public class ClassLoaderFilter implements Filter { + @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // 获得原来的类加载器 ClassLoader ocl = Thread.currentThread().getContextClassLoader(); + // 切换当前线程的类加载器为服务接口的类加载器 Thread.currentThread().setContextClassLoader(invoker.getInterface().getClassLoader()); + // 服务调用 try { return invoker.invoke(invocation); } finally { + // 切换当前线程的类加载器为原来的类加载器 Thread.currentThread().setContextClassLoader(ocl); } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ConsumerContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ConsumerContextFilter.java index b5675e523..2f50ec1f0 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ConsumerContextFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ConsumerContextFilter.java @@ -30,23 +30,28 @@ import com.alibaba.dubbo.rpc.RpcInvocation; /** * ConsumerContextInvokerFilter * + * 服务消费者的 ContextFilter */ @Activate(group = Constants.CONSUMER, order = -10000) public class ConsumerContextFilter implements Filter { + @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // 设置 RpcContext 对象 RpcContext.getContext() .setInvoker(invoker) .setInvocation(invocation) - .setLocalAddress(NetUtils.getLocalHost(), 0) - .setRemoteAddress(invoker.getUrl().getHost(), - invoker.getUrl().getPort()); + .setLocalAddress(NetUtils.getLocalHost(), 0) // 本地地址 + .setRemoteAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort()); // 远程地址 + // 设置 RpcInvocation 对象的 `invoker` 属性 if (invocation instanceof RpcInvocation) { ((RpcInvocation) invocation).setInvoker(invoker); } + // 服务调用 try { return invoker.invoke(invocation); } finally { + // 清理隐式参数集合 RpcContext.getContext().clearAttachments(); } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java index 4305daf62..2902cb54d 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java @@ -32,11 +32,14 @@ import java.util.Map; /** * ContextInvokerFilter * + * 服务提供者的 ContextFilter */ @Activate(group = Constants.PROVIDER, order = -10000) public class ContextFilter implements Filter { + @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // 创建新的 `attachments` 集合,清理公用的隐式参数 Map attachments = invocation.getAttachments(); if (attachments != null) { attachments = new HashMap(attachments); @@ -46,17 +49,18 @@ public class ContextFilter implements Filter { attachments.remove(Constants.DUBBO_VERSION_KEY); attachments.remove(Constants.TOKEN_KEY); attachments.remove(Constants.TIMEOUT_KEY); - attachments.remove(Constants.ASYNC_KEY);// Remove async property to avoid being passed to the following invoke chain. + attachments.remove(Constants.ASYNC_KEY); // Remove async property to avoid being passed to the following invoke chain. + // 清空消费端的异步参数 } + // 设置 RpcContext 对象 RpcContext.getContext() .setInvoker(invoker) .setInvocation(invocation) // .setAttachments(attachments) // merged from dubbox - .setLocalAddress(invoker.getUrl().getHost(), - invoker.getUrl().getPort()); - + .setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort()); // mreged from dubbox // we may already added some attachments into RpcContext before this filter (e.g. in rest protocol) + // 在此过滤器(例如rest协议)之前,我们可能已经在RpcContext中添加了一些附件。 if (attachments != null) { if (RpcContext.getContext().getAttachments() != null) { RpcContext.getContext().getAttachments().putAll(attachments); @@ -64,14 +68,17 @@ public class ContextFilter implements Filter { RpcContext.getContext().setAttachments(attachments); } } - + // 设置 RpcInvocation 对象的 `invoker` 属性 if (invocation instanceof RpcInvocation) { ((RpcInvocation) invocation).setInvoker(invoker); } + // 服务调用 try { return invoker.invoke(invocation); } finally { + // 移除上下文 RpcContext.removeContext(); } } + } \ No newline at end of file -- GitLab