跟着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这个接口的话,会多出来多少类文件啊。

posted on 2021-05-21 15:08  MaXianZhe  阅读(82)  评论(0编辑  收藏  举报

导航