轉載: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()))