Dubbo源码解析(八)Dubbo Filter 之 FilterChain

首先通过 ProtocolFilterWrapper 包装Protocol,这样所有的发布与引用服务逻辑都需要走到ProtocolFilterWrapper的逻辑。
ProtocolFilterWrapper.java

public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        // registry 协议特判
        if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
            return protocol.export(invoker);
        }
        return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
    }

    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        // registry 协议特判,因为RegistryInvoker不是真正的invoker实现,只是一个包装,为了让客户端看起来是一个invoker,实则是一个集群,会导致拦截器拦截了两遍。
        if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
            return protocol.refer(type, url);
        }
        return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
    }

不占用额外的引用空间构造的链表结构
利用内存地址的指向实现,真是漂漂亮亮
怎么就没有想到呢。。。。
之前都是通过一个集合保存所有filter的引用,
ProtocolFilterWrapper.java

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.isEmpty()) {
            // 由内而外一层一层包装,所以顺序上面需要从最后的filter开始
            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;
    }
相关文章
相关标签/搜索