如果咱们在同一个办法自定义多个AOP,如何执行执行程序?
有一种答案是指定order,order越小越先执行。这种答案不算错,然而有些全面。
更改Aspect的Order有三中形式,1:通过实现org.springframework.core.Ordered接口;2:通过注解@Order(1) ;3:通过配置文件配置
咱们试验采纳注解的形式,定义两个Aspect:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface Log { String description() default "";}
order=1001代码块java@Aspect@Component@Order(1001)public class LogAspect { private final Logger logger \= LoggerFactory.getLogger(this.getClass()); //日志注解 @Pointcut(value \= "@annotation(com.meituan.pay.mapi.aspect.Log)") public void logAspect() { } //申明前置告诉 @Before("logAspect()") public void doBefore(JoinPoint point) { logger.info("logAspect:doBefore"); return; } //申明后置告诉 @AfterReturning(pointcut \= "logAspect()", returning \= "returnValue") public void doAfterReturning(JoinPoint point, Object returnValue) { logger.info("logAspect:doAfterReturning"); } //申明例外告诉 @AfterThrowing(pointcut \= "logAspect()", throwing \= "e") public void doAfterThrowing(Exception e) { logger.info("logAspect:doAfterThrowing"); } //申明最终告诉 @After("logAspect()") public void doAfter() { logger.info("logAspect:doAfter"); } //申明盘绕告诉 @Around("logAspect()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { logger.info("logAspect:doAround-start"); Object obj \= pjp.proceed(); logger.info("logAspect:doAround-end"); return obj; }}**SignAspect:**代码块java@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface Sign { String description() default "";}order=1002代码块java@Aspect@Component@Order(1002)public class SignAspect { private final Logger logger \= LoggerFactory.getLogger(this.getClass()); //日志注解 @Pointcut(value \= "@annotation(com.meituan.pay.mapi.aspect.Sign)") public void signAspect() { } //申明前置告诉 @Before("signAspect()") public void doBefore(JoinPoint point) { logger.info("signAspect:doBefore"); return; } //申明后置告诉 @AfterReturning(pointcut \= "signAspect()", returning \= "returnValue") public void doAfterReturning(JoinPoint point, Object returnValue) { logger.info("signAspect:doAfterReturning"); } //申明例外告诉 @AfterThrowing(pointcut \= "signAspect()", throwing \= "e") public void doAfterThrowing(Exception e) { logger.info("signAspect:doAfterThrowing"); } //申明最终告诉 @After("signAspect()") public void doAfter() { logger.info("signAspect:doAfter"); } //申明盘绕告诉 @Around("signAspect()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { logger.info("signAspect:doAround-start"); Object obj \= pjp.proceed(); logger.info("signAspect:doAround-end"); return obj; }}
**测试:**代码块java@Servicepublic class AspectTestService { private static final Logger LOGGER \= LoggerFactory.getLogger(AspectTestService.class); @Sign @Log public void testAspect() { LOGGER.info("执行办法"); }}
**最终输入:**代码块javaLogAspect (LogAspect.java:55) logAspect:doAround\-startLogAspect (LogAspect.java:30) logAspect:doBeforeSignAspect (SignAspect.java:54) signAspect:doAround\-startSignAspect (SignAspect.java:29) signAspect:doBeforeAspectTestService (AspectTestService.java:19) 执行办法SignAspect (SignAspect.java:56) signAspect:doAround\-endSignAspect (SignAspect.java:48) signAspect:doAfterSignAspect (SignAspect.java:36) signAspect:doAfterReturningLogAspect (LogAspect.java:57) logAspect:doAround\-endLogAspect (LogAspect.java:49) logAspect:doAfterLogAspect (LogAspect.java:37) logAspect:doAfterReturning**论断:**从下面的测试咱们看到,的确是order越小越是最先执行,但更重要的是最先执行的最初完结。AOP就是面向切面编程,什么是切面,画一个图来了解下:
由此得出:
- spring aop就是一个同心圆,要执行的办法为圆心,最外层的order最小
- 从最外层依照LogAspect、SignAspect的程序顺次执行doAround办法,doBefore办法
- 而后执行method办法
- 最初依照SignAspect、LogAspect的程序顺次执行doAfter、doAfterReturn办法
- 也就是说对多个AOP来说,先before的,肯定后after
利用举例:
如果咱们要在同一个办法事务提交后执行本人的AOP,那么把事务的AOP order设置为2,本人的AOP order设置为1,而后在doAfterReturn里边解决本人的业务逻辑