• 跟着pigeon学习写责任链


    刚才在看pigeon的源码,发现一处责任链写的是真牛逼啊

    private static <K, V extends ServiceInvocationFilter> ServiceInvocationHandler createInvocationHandler(
                List<V> internalFilters) {
            ServiceInvocationHandler last = null;
            List<V> filterList = new ArrayList<V>();
            filterList.addAll(internalFilters);
            for (int i = filterList.size() - 1; i >= 0; i--) {
                final V filter = filterList.get(i);
                final ServiceInvocationHandler next = last;
                last = new ServiceInvocationHandler() {
                    @SuppressWarnings("unchecked")
                    @Override
                    public InvocationResponse handle(InvocationContext invocationContext) throws Throwable {
                        return filter.invoke(next, invocationContext);
                    }
                };
            }
            return last;
        }

    注意是逆序哦  BusinessProcessFilter 是最后执行的,所以 ServiceInvocationHandler handler不会继续传递,也就没有调用

    public class BusinessProcessFilter implements ServiceInvocationFilter<ProviderContext> {
    
        private static final Logger logger = LoggerLoader.getLogger(BusinessProcessFilter.class);
    
        private static final String KEY_TIMEOUT_RESET = "pigeon.timeout.reset";
    
    
        @Override
        public InvocationResponse invoke(ServiceInvocationHandler handler, ProviderContext invocationContext)
                throws Throwable {
            invocationContext.getTimeline().add(new TimePoint(TimePhase.U));
            InvocationRequest request = invocationContext.getRequest();
            if (request.getMessageType() == Constants.MESSAGE_TYPE_SERVICE) {
                if (ConfigManagerLoader.getConfigManager().getBooleanValue(KEY_TIMEOUT_RESET, true)
                        && request.getTimeout() > 0) {
                    ContextUtils.putLocalContext(Constants.REQUEST_TIMEOUT, request.getTimeout());
                }
                if (Thread.currentThread().isInterrupted()) {
                    StringBuilder msg = new StringBuilder();
                    msg.append("the request has been canceled by timeout checking processor:").append(request);
                    throw new RequestAbortedException(msg.toString());
                }
                List<ProviderProcessInterceptor> interceptors = ProviderProcessInterceptorFactory.getInterceptors();
                for (ProviderProcessInterceptor interceptor : interceptors) {
                    interceptor.preInvoke(request);
                }
                List<ProviderInterceptor> contextInterceptors = ProviderInterceptorFactory.getInterceptors();
                for (ProviderInterceptor interceptor : contextInterceptors) {
                    interceptor.preInvoke(invocationContext);
                }
                InvocationResponse response = null;
                ServiceMethod method = invocationContext.getServiceMethod();
                if (method == null) {
                    method = ServiceMethodFactory.getMethod(request);
                }
                if (Constants.REPLY_MANUAL) {
                    if (request.getCallType() == Constants.CALLTYPE_REPLY) {
                        request.setCallType(Constants.CALLTYPE_MANUAL);
                    }
                }
                ProviderHelper.setContext(invocationContext);
                invocationContext.getTimeline().add(new TimePoint(TimePhase.M, System.currentTimeMillis()));
                Object returnObj = null;
                try {
                    returnObj = method.invoke(request.getParameters());
                } finally {
                    ProviderHelper.clearContext();
                }
    
                invocationContext.getTimeline().add(new TimePoint(TimePhase.M, System.currentTimeMillis()));
                if (request.getCallType() == Constants.CALLTYPE_REPLY) {
                    response = ProviderUtils.createSuccessResponse(request, returnObj);
                }
                return response;
            }
            throw new BadRequestException("message type[" + request.getMessageType() + "] is not supported!");
        }
    
    }

      HeartbeatProcessFilter

    public class HeartbeatProcessFilter implements ServiceInvocationFilter<ProviderContext> {
    
        private static final Logger logger = LoggerLoader.getLogger(HeartbeatProcessFilter.class);
    
        @Override
        public InvocationResponse invoke(ServiceInvocationHandler handler, ProviderContext invocationContext)
                throws Throwable {
            if (invocationContext.getRequest().getMessageType() == Constants.MESSAGE_TYPE_HEART) {
                return ProviderUtils.createHeartResponse(invocationContext.getRequest());
            }//执行逻辑,如果不该自己处理,则调用传入的handler进行处理传递
            return handler.handle(invocationContext);
        }
    
    }

     最牛逼的地方我觉得是 ServiceInvocationHandler就是接口,上面的责任链是通过匿名类的方式直接构造成了链,都不需要定义那么多类了。如果每一个都实现

    ServiceInvocationHandler这个接口的话,会多出来多少类文件啊。

  • 相关阅读:
    [Linux]-配置多台机器的SSH相互信任
    [Linux]-常用代码块
    [Linux]-Shell编程与规范
    [Sqoop]-任务
    [Sqoop]-导入导出
    [Sqoop]-认识&部署
    [Hive]-函数篇
    Tomcat catalina.out日志使用log4j按天分割
    技术站点
    Linux监控命令
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14793897.html
Copyright © 2020-2023  润新知