原文: https://howtodoinjava.com/spring-aop/spring-aop-specifying-aspects-ordering/

在上一个教程中,我们了解了 spring aop 关键术语和示例 。 这些我们创建了一个日志记录切面,然后应用于UserManager类。 假设您的应用程序中有多个切面,并且可以将它们应用于某种方法。 如果将多个切面应用到同一个连接点,除非您使用@Order注解或org.springframework.core.Ordered接口明确指定了切面,否则将不会确定这些切面的优先级/顺序。 在这个例子中,我们将看到一个有序切面的例子。

指定切面顺序

如前所述,要指定切面的顺序,您有两种方法:

1)使用@Order注解指定切面的排序

这很简单。 使用如下注解。

  1. @Aspect
  2. @Order(0)
  3. public class EmployeeCRUDTransactionAspect
  4. {
  5. @Before("execution(* EmployeeManager.getEmployeeById(..))")
  6. public void getEmployeeById(JoinPoint joinPoint)
  7. {
  8. System.out.println("EmployeeCRUDTransactionAspect.getEmployeeById() : " + joinPoint.getSignature().getName());
  9. }
  10. }
  11. @Aspect
  12. @Order(1)
  13. public class EmployeeCRUDLoggingAspect
  14. {
  15. @Before("execution(* EmployeeManager.getEmployeeById(..))")
  16. public void logBefore(JoinPoint joinPoint)
  17. {
  18. System.out.println("EmployeeCRUDAspect.logBefore() : " + joinPoint.getSignature().getName());
  19. }
  20. }

2)通过实现org.springframework.core.Ordered接口指定切面排序

这太容易了。

  1. @Aspect
  2. public class EmployeeCRUDLoggingAspect implements Ordered
  3. {
  4. //Override this method
  5. public int getOrder() {
  6. return 0;
  7. }
  8. @Before("execution(* EmployeeManager.getEmployeeById(..))")
  9. public void logBefore(JoinPoint joinPoint)
  10. {
  11. System.out.println("EmployeeCRUDAspect.logBefore() : " + joinPoint.getSignature().getName());
  12. }
  13. }
  14. @Aspect
  15. public class EmployeeCRUDTransactionAspect implements Ordered
  16. {
  17. //Override this method
  18. public int getOrder() {
  19. return 1;
  20. }
  21. @Before("execution(* EmployeeManager.getEmployeeById(..))")
  22. public void getEmployeeById(JoinPoint joinPoint)
  23. {
  24. System.out.println("EmployeeCRUDTransactionAspect.getEmployeeById() : " + joinPoint.getSignature().getName());
  25. }
  26. }

现在该测试顺序是否有效。 在applicationContext.xml文件中配置两个切面。

  1. <aop:aspectj-autoproxy />
  2. <context:component-scan base-package="com.howtodoinjava.demo.aop" />
  3. <bean id="transactionAspect" class="com.howtodoinjava.demo.aop.EmployeeCRUDTransactionAspect" />
  4. <bean id="loggingAspect" class="com.howtodoinjava.demo.aop.EmployeeCRUDLoggingAspect" />

让我们运行以下示例:

  1. public class TestAOP
  2. {
  3. @SuppressWarnings("resource")
  4. public static void main(String[] args)
  5. {
  6. ApplicationContext context = new ClassPathXmlApplicationContext("com/howtodoinjava/demo/aop/applicationContext.xml");
  7. EmployeeManager manager = context.getBean(EmployeeManager.class);
  8. manager.getEmployeeById(1);
  9. }
  10. }
  11. Output:
  12. EmployeeCRUDAspect.logBefore() : getEmployeeById
  13. EmployeeCRUDTransactionAspect.getEmployeeById() : getEmployeeById
  14. Method getEmployeeById() called

很棒。 Spring AOP 切面的顺序正在按预期工作。

祝您学习愉快!