dubbo原始碼之攔截呼叫
阿新 • • 發佈:2019-01-24
dubbo在生成呼叫者和被呼叫者的動態代理的時候會生成呼叫鏈,在攔截呼叫鏈走完後才會進入真正的方法呼叫,攔截呼叫分別在消費者端和呼叫者端都生成了呼叫鏈,程式碼如下:
消費者端行成呼叫鏈:
提供者端形成呼叫鏈:public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException { if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { return protocol.refer(type, url); } return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER); }
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) { return protocol.export(invoker); } return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER)); }
消費者端和提供者端形成呼叫鏈都呼叫了同一段程式碼:buildInvokerChain()
這就是呼叫鍊形成的原始碼,通過last->next的方式統一新增,然後再新生成的Invoker中呼叫next然後最後呼叫last就是我們真正執行的Invoker,呼叫鏈分類(預設Filter)如下:private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) { Invoker<T> last = invoker; List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group); if (filters.size() > 0) { for (int i = filters.size() - 1; i >= 0; i --) { final Filter filter = filters.get(i); final Invoker<T> next = last; last = new Invoker<T>() { public Class<T> getInterface() { return invoker.getInterface(); } public URL getUrl() { return invoker.getUrl(); } public boolean isAvailable() { return invoker.isAvailable(); } 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; }