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