前言 在我们开发过程中,会经常碰到这么一些需求,比如在在主流程执行前,要做一些前置事件,在主流程执行之后,做一些收尾工作。对一些新手程序员,他可能会直接写类似如下的代码publicvoidexecute(){doBefore();doBiz();doAfter();}复制代码 对有一定工作经验的程序员,他可能会用AOP或者用一些设计模式比如模板模式。那我们今天来聊聊下使用springspiaop责任链来实现上面的需求代码实现过程分析 假设主流程只需做一次前置处理和一次后置处理,则伪代码如下publicvoidexecute(){doBefore();doBiz();doAfter();}复制代码 此时我们可以用模板模式或者AOP,这边我们采用AOP。其伪代码如下publicclassCorMethodInterceptorimplementsMethodInterceptor{OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{try{doBefore();Objectresultinvocation。proceed();}catch(Throwablethrowable){log。error({},e);}finally{doAfter();}returnnull}}复制代码 如果对这种写法不适应,可以采用AspectAround方式,效果一个样。 当主流程需要多次前置处理和多次后置处理时,我们的代码可能就变成publicclassCorMethodInterceptorimplementsMethodInterceptor{OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{try{doBefore();doBefore();doBefore();。。。。Objectresultinvocation。proceed();}catch(Throwablethrowable){log。error({},e);}finally{doAfter();doAfter();doAfter();。。。}returnnull}}复制代码 此时这些前置处理或者后置处理看起来就像是一条链,于是我们就可以考虑采用一些设计模式比如责任链或者采用管道模式。本示例我们使用责任链模式代码实现 1、创建处理器接口publicinterfaceAbstarctHandlerextendsOrdered{预处理回调,实现服务的预处理returntrue表示流程继续,false表示流程中断,不会继续调用其他处理器或者服务defaultbooleanpreHandler(Invocationinvocation){}整个请求处理完毕回调方法。类似trycatchfinally中的finally。多个afterCompletion按倒叙输出defaultvoidafterCompletion(Invocationinvocation){}}复制代码 2、创建处理器链publicclassMethodInterceptorChain{privatefinalListabstarctHandlersnewArrayList();publicvoidaddHandler(AbstarctHandlerhandler){abstarctHandlers。add(handler);}publicListgetHanlders(){if(CollectionUtils。isEmpty(abstarctHandlers)){returnCollections。emptyList();}AnnotationAwareOrderComparator。sort(abstarctHandlers);returnCollections。unmodifiableList(abstarctHandlers);}}复制代码 3、业务逻辑和责任链整合DataAllArgsConstructorNoArgsConstructorpublicclassCorHandlerInterceptor{privateMethodInterceptorCpublicObjectinvoke(Invocationinvocation)throwsException{ListabstarctHandlerschain。getHanlders();if(CollectionUtils。isEmpty(abstarctHandlers)){invocation。invoke();}booleanisCanEintcanExecCount0;for(AbstarctHandlerabstarctHandler:abstarctHandlers){canExecCif(!abstarctHandler。preHandler(invocation)){isCanE}}try{if(isCanExec){returninvocation。invoke();}}catch(Exceptione){thrownewException(e);}finally{for(inti0;icanExecCi){intjcanExecCounti1;abstarctHandlers。get(j)。afterCompletion(invocation);}}}}复制代码 4、创建AOP切面publicclassCorMethodInterceptorimplementsMethodInterceptor{privateCorHandlerInterceptorcorHandlerIpublicCorMethodInterceptor(CorHandlerInterceptorcorHandlerInterceptor){this。corHandlerInterceptorcorHandlerI}OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{InvocationinvokerInvocation。builder()。args(invocation。getArguments())。method(invocation。getMethod())。target(invocation。getThis())。build();returncorHandlerInterceptor。invoke(invoker);}}复制代码 5、配置切点BeanConditionalOnMissingBeanpublicAspectJExpressionPointcutAdvisoraspectJExpressionPointcutAdvisor(PointcutProperitespointcutProperites,CorHandlerInterceptorcorHandlerInterceptor){AspectJExpressionPointcutAdvisoraspectJExpressionPointcutAdvisornewAspectJExpressionPointcutAdvisor();aspectJExpressionPointcutAdvisor。setExpression(pointcutProperites。getExpression());aspectJExpressionPointcutAdvisor。setAdvice(newCorMethodInterceptor(corHandlerInterceptor));returnaspectJExpressionPointcutA}复制代码 6、处理器注入springBeanConditionalOnMissingBeanpublicCorHandlerInterceptorcorHandlerInterceptor(ObjectProviderListprovider){MethodInterceptorChainmethodInterceptorChainnewMethodInterceptorChain();loadedHandlerBySpring(provider,methodInterceptorChain);loadedHanlderBySpi(methodInterceptorChain);CorHandlerInterceptorcorHandlerInterceptornewCorHandlerInterceptor();corHandlerInterceptor。setChain(methodInterceptorChain);returncorHandlerI}BeanConditionalOnMissingBeanpublicDefaultHandlerdefaultHandler(){returnnewDefaultHandler();}privatevoidloadedHanlderBySpi(MethodInterceptorChainmethodInterceptorChain){ServiceLoaderserviceLoaderServiceLoader。load(AbstarctHandler。class);IteratoriteratorserviceLoader。iterator();while(iterator。hasNext()){AbstarctHandlerabstarctHandleriterator。next();log。info(loadhanderbyspi【{}】,abstarctHandler。getClass()。getName());methodInterceptorChain。addHandler(abstarctHandler);}}privatevoidloadedHandlerBySpring(ObjectProviderListprovider,MethodInterceptorChainmethodInterceptorChain){ListgetListBySpringprovider。getIfAvailable();if(!CollectionUtils。isEmpty(getListBySpring)){for(AbstarctHandlerabstarctHandler:getListBySpring){log。info(loadhanderbyspring【{}】,abstarctHandler。getClass()。getName());methodInterceptorChain。addHandler(abstarctHandler);}}}复制代码示例演示 1、编写业务服务publicinterfaceHelloService{StringsayHello(Stringusername);}复制代码ServicepublicclassHelloServiceImplimplementsHelloService{OverridepublicStringsayHello(Stringusername){returnhello:}}复制代码 2、编写处理器 一种通过ComponentComponentpublicclassHelloServiceNameInterceptorimplementsAbstarctHandler{OverridepublicbooleanpreHandler(Invocationinvocation){Object〔〕argsinvocation。getArgs();System。out。println(名称校验preHandler);for(Objectarg:args){if(张三。equals(arg)){}}}OverridepublicvoidafterCompletion(Invocationinvocation){System。out。println(名称校验afterCompletion:Arrays。toString(invocation。getArgs()));}OverridepublicintgetOrder(){return102;}}复制代码 一种通过SPIpublicclassHelloServiceSpiInterceptorimplementsAbstarctHandler{OverridepublicbooleanpreHandler(Invocationinvocation){Object〔〕argsinvocation。getArgs();System。out。println(参数转换preHandler);for(inti0;iargs。i){if(lisi。equals(args〔i〕)){args〔i〕李四;}}}OverridepublicvoidafterCompletion(Invocationinvocation){System。out。println(参数转换afterCompletion:Arrays。toString(invocation。getArgs()));}OverridepublicintgetOrder(){return1;}}复制代码 配置SPI 内容如下com。github。lybgeek。cor。test。interceptor。HelloServiceSpiInterceptor复制代码 3、配置切点表达式lybgeek:pointcut:expression:execution(com。github。lybgeek。cor。test。service。。。(。。))复制代码 4、测试 观察控制台 发现处理器正常工作总结 所谓的可扩展,指在新增功能时,不需要或者少修改原有的功能。用设计原则来讲就是对修改关闭,对扩展开放。本文的示例如果心细的朋友就会发现,这跟springmvc的拦截器实现是很像的 作者:linyb极客之路 链接:https:juejin。cnpost7080330791423016990