转载:https://www.jianshu.com/p/f390bb88574d
filter在dubbo中的应用非常广泛,它可以对服务端、消费端的调用过程进行拦截,从而对dubbo进行功能上的扩展,我们所熟知的RpcContext就用到了filter。本文主要尝试从以下3个方面来简单介绍一下dubbo中的filter:
1.filter链原理
2.自定义filter
3.使用filter透传traceId
1.filter链原理
dubbo中filter链的入口在ProtocolFilterWrapper中,这是Protocol的一个包装类,在其服务暴露和服务引用时都进行了构建filter链的工作。
// 构建filter链 private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) { Invoker<T> last = invoker; // 获取可用的filter列表 List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group); if (!filters.isEmpty()) { for (int i = filters.size() - 1; i >= 0; i--) { final Filter filter = filters.get(i); final Invoker<T> next = last; // 典型的装饰器模式,将invoker用filter逐层进行包装 last = new Invoker<T>() { public Class<T> getInterface() { return invoker.getInterface(); } public URL getUrl() { return invoker.getUrl(); } public boolean isAvailable() { return invoker.isAvailable(); } // 重点,每个filter在执行invoke方法时,会触发其下级节点的invoke方法,最后一级节点即为最原始的服务 public Result invoke(Invocation invocation) throws RpcException { return filter.invoke(next, invocation); } public void destroy() { invoker.destroy(); } @Override public String toString() { return invoker.toString(); } }; } } return last; } // 服务端暴露服务 public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol()))