指定切面的优先级:
在同一个链接点上应用不止一个切面时 , 除非明确指定 , 否则它们的优先级是不确定的。
切面的优先级可以通过实现 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] |
重用切入点表达式:
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 }