Spring学习--切面优先级及重用切点表达式

指定切面的优先级:

在同一个链接点上应用不止一个切面时 , 除非明确指定 , 否则它们的优先级是不确定的。

切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定。

实现 Ordered 接口 , getOrder() 方法的返回值越小 , 优先级越高 , 若使用 @Order 注解 , 序号出现在注解中 , 数字越小优先级越高。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:aop="http://www.springframework.org/schema/aop"
 5        xmlns:context="http://www.springframework.org/schema/context"
 6        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
 8        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 9 
10     <!-- IOC 扫描包 -->
11     <context:component-scan base-package="com.itdoc.spring.aop.circular"></context:component-scan>
12     <!-- 使 AspectJ 注解起作用, 自动为匹配的类生成代理对象 -->
13     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
14 
15 </beans>
 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * http://www.cnblogs.com/goodcheap
 7  *
 8  * @author: Wáng Chéng Dá
 9  * @create: 2017-03-03 19:34
10  */
11 public interface Arithmetic {
12 
13     int add(int i, int j);
14 
15     int sub(int i, int j);
16 
17     int mul(int i, int j);
18 
19     int div(int i, int j);
20 
21 }
 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * http://www.cnblogs.com/goodcheap
 7  *
 8  * @author: Wáng Chéng Dá
 9  * @create: 2017-03-03 19:35
10  */
11 @Component("arithmetic")
12 public class ArithmeticImpl implements Arithmetic {
13     @Override
14     public int add(int i, int j) {
15         int result = i + j;
16         return result;
17     }
18 
19     @Override
20     public int sub(int i, int j) {
21         int result = i - j;
22         return result;
23     }
24 
25     @Override
26     public int mul(int i, int j) {
27         int result = i * j;
28         return result;
29     }
30 
31     @Override
32     public int div(int i, int j) {
33         int result = i / j;
34         return result;
35     }
36 }
 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.Around;
 5 import org.aspectj.lang.annotation.Aspect;
 6 import org.springframework.stereotype.Component;
 7 
 8 import java.util.Arrays;
 9 
10 /**
11  * 通知
12  * http://www.cnblogs.com/goodcheap
13  *
14  * @author: Wáng Chéng Dá
15  * @create: 2017-03-04 9:50
16  */
17 @Aspect
18 @Component
19 public class AsjectLogging {
20 
21     /**
22      * 环绕通知需携带 ProceedingJoinPoint 类型的参数。
23      * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型参数可以决定是否执行目标方法。
24      * 环绕通知必须有返回值, 返回值即目标方法的返回值。
25      *
26      * @param point
27      * @return
28      */
29     @Around("execution(* com.itdoc.spring.aop.circular.*.*(..))")
30     public Object around(ProceedingJoinPoint point) {
31         Object methodName = point.getSignature().getName();
32         Object[] args = point.getArgs();
33         Object result = null;
34         try {
35             //前置通知
36             System.out.println("The method " + methodName + " begins with" + Arrays.asList(args));
37             //执行方法
38             result = point.proceed();
39             //返回通知
40             System.out.println("The method " + methodName + " ends with " + result);
41         } catch (Throwable e) {
42             e.printStackTrace();
43             //异常通知
44             System.out.println("The method " + methodName + " exception with " + e);
45         } finally {
46             //后置通知
47             System.out.println("The method " + methodName + " ends");
48         }
49         return result;
50     }
51 }
 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.Before;
 5 import org.springframework.core.annotation.Order;
 6 import org.springframework.stereotype.Component;
 7 
 8 /**
 9  * http://www.cnblogs.com/goodcheap
10  *
11  * @author: Wáng Chéng Dá
12  * @create: 2017-03-04 12:20
13  */
14 @Order(2147483647)
15 @Aspect
16 @Component
17 public class Validate {
18 
19     @Before("execution(* com.itdoc.spring.aop.circular.*.*(..))")
20     public void beforeValidate() {
21         System.out.println("I am Validate's beforeValidate method...");
22     }
23 }
 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 /**
 7  * http://www.cnblogs.com/goodcheap
 8  *
 9  * @author: Wáng Chéng Dá
10  * @create: 2017-03-04 9:54
11  */
12 public class Main {
13 
14     public static void main(String[] args) {
15         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
16         Arithmetic arithmetic = (Arithmetic) ctx.getBean("arithmetic");
17         System.out.println("result = " + arithmetic.div(1, 1));
18     }
19 }

控制台输出:

The method div begins with[1, 1]
I am Validate's beforeValidate method...
The method div ends with 1
The method div ends
result = 1

重用切入点表达式:

 1 package com.itdoc.spring.aop.circular;
 2 
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.Before;
 5 import org.aspectj.lang.annotation.Pointcut;
 6 import org.springframework.core.annotation.Order;
 7 import org.springframework.stereotype.Component;
 8 
 9 /**
10  * http://www.cnblogs.com/goodcheap
11  *
12  * @author: Wáng Chéng Dá
13  * @create: 2017-03-04 12:20
14  */
15 @Order(2147483647)
16 @Aspect
17 @Component
18 public class Validate {
19 
20     @Pointcut("execution(* com.itdoc.spring.aop.circular.*.*(..))")
21     public void declareJointPointExpression() {}
22 
23     /**
24      * 同包引入可以不写包名, 若是不同包引用需要引入包名。
25      */
26     @Before("com.itdoc.spring.aop.circular.Validate.declareJointPointExpression()")
27     public void beforeValidate() {
28         System.out.println("I am Validate's beforeValidate method...");
29     }
30 }
原文地址:https://www.cnblogs.com/chinda/p/6501034.html