Dubbo源码解读——过滤器

原创
2020/04/12 22:37
阅读数 605

Dubbo源码解读——过滤器

目录

Dubbo源码解读——过滤器    1、Dubbo过滤器整体结构    2、Dubbo过滤器的使用   3、过滤器链   4、记录的知识点

1、Dubbo过滤器整体结构

  • dubbo主要过滤器在dubbo-rpc下的dubbo-rpc-api模块。

  • 总体结构:

2、Dubbo过滤器的使用

  • 使用@Activate注解默认启用

  • 消费方可以配置filter的调用过程拦截

  • 服务方也可配置filter的调用过程拦截

  • filter = {"dubboExceptionFilter","-exception"} “-”是剔除对应的过滤器

3、过滤器链

  • 过滤器链是如何组装的:类:ProtocolFilterWrapper 核心方法:buildInvokerChain

  • 暴露服务时:

    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        if (UrlUtils.isRegistry(invoker.getUrl())) {
            return protocol.export(invoker);
        }
        return protocol.export(buildInvokerChain(invoker, SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
    }
  • 引用远程服务时:

    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        if (UrlUtils.isRegistry(url)) {
            return protocol.refer(type, url);
        }
        return buildInvokerChain(protocol.refer(type, url), REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
    }
  • 核心方法解析:buildInvokerChain

    获取并遍历所有过滤器

    组装过滤器链,(这个地方用到了装饰器模式,增强了原有的Invoker)

    @Override
    public Result invoke(Invocation invocation) throws RpcException {
        Result asyncResult;
        try {
            // 设置过滤器的下一个节点,不断循环形成过滤器链
            asyncResult = filter.invoke(next, invocation);
        } catch (Exception e) {
            if (filter instanceof ListenableFilter) {
                ListenableFilter listenableFilter = ((ListenableFilter) filter);
                try {
                    Filter.Listener listener = listenableFilter.listener(invocation);
                    if (listener != null) {
                        listener.onError(e, invoker, invocation);
                    }
                } finally {
                    listenableFilter.removeListener(invocation);
                }
            } else if (filter instanceof Filter.Listener) {
                Filter.Listener listener = (Filter.Listener) filter;
                listener.onError(e, invoker, invocation);
            }
            throw e;
        } finally {
    
        }
        // 方法调用完成时,启动回调
        return asyncResult.whenCompleteWithContext((r, t) -> {
            if (filter instanceof ListenableFilter) {
                ListenableFilter listenableFilter = ((ListenableFilter) filter);
                Filter.Listener listener = listenableFilter.listener(invocation);
                try {
                    if (listener != null) {
                        if (t == null) {
                            listener.onResponse(r, invoker, invocation);
                        } else {
                            listener.onError(t, invoker, invocation);
                        }
                    }
                } finally {
                    listenableFilter.removeListener(invocation);
                }
            } else if (filter instanceof Filter.Listener) {
                Filter.Listener listener = (Filter.Listener) filter;
                if (t == null) {
                    listener.onResponse(r, invoker, invocation);
                } else {
                    listener.onError(t, invoker, invocation);
                }
            }
        });
    }

4、记录的知识点

  • Dubbo中每个过滤器的使用方式不一样,有的是服务提供者使用,有的是消费者使用。

  • Dubbo使用注解@Activate(group = PROVIDER, order=-1000)设置过滤器激活的条件和顺序。

  • CompletableFuture:1.8提供的并发编程工具类。通过回调处理计算的结果。

  • 使用了装饰器模式来增强原有Invoker.(AbstractInvoker && public interface Invoker<T> extends Node)


展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部