指定切面的优先级:

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

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

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

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- IOC 扫描包 -->
<context:component-scan base-package="com.itdoc.spring.aop.circular"></context:component-scan>
<!-- 使 AspectJ 注解起作用, 自动为匹配的类生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
 package com.itdoc.spring.aop.circular;

 import org.springframework.stereotype.Component;

 /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:34
*/
public interface Arithmetic { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); }
 package com.itdoc.spring.aop.circular;

 import org.springframework.stereotype.Component;

 /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:35
*/
@Component("arithmetic")
public class ArithmeticImpl implements Arithmetic {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
} @Override
public int sub(int i, int j) {
int result = i - j;
return result;
} @Override
public int mul(int i, int j) {
int result = i * j;
return result;
} @Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
 package com.itdoc.spring.aop.circular;

 import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component; import java.util.Arrays; /**
* 通知
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-04 9:50
*/
@Aspect
@Component
public class AsjectLogging { /**
* 环绕通知需携带 ProceedingJoinPoint 类型的参数。
* 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型参数可以决定是否执行目标方法。
* 环绕通知必须有返回值, 返回值即目标方法的返回值。
*
* @param point
* @return
*/
@Around("execution(* com.itdoc.spring.aop.circular.*.*(..))")
public Object around(ProceedingJoinPoint point) {
Object methodName = point.getSignature().getName();
Object[] args = point.getArgs();
Object result = null;
try {
//前置通知
System.out.println("The method " + methodName + " begins with" + Arrays.asList(args));
//执行方法
result = point.proceed();
//返回通知
System.out.println("The method " + methodName + " ends with " + result);
} catch (Throwable e) {
e.printStackTrace();
//异常通知
System.out.println("The method " + methodName + " exception with " + e);
} finally {
//后置通知
System.out.println("The method " + methodName + " ends");
}
return result;
}
}
 package com.itdoc.spring.aop.circular;

 import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-04 12:20
*/
@Order(2147483647)
@Aspect
@Component
public class Validate { @Before("execution(* com.itdoc.spring.aop.circular.*.*(..))")
public void beforeValidate() {
System.out.println("I am Validate's beforeValidate method...");
}
}
 package com.itdoc.spring.aop.circular;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-04 9:54
*/
public class Main { public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Arithmetic arithmetic = (Arithmetic) ctx.getBean("arithmetic");
System.out.println("result = " + arithmetic.div(1, 1));
}
}

控制台输出:

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

重用切入点表达式:

 package com.itdoc.spring.aop.circular;

 import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-04 12:20
*/
@Order(2147483647)
@Aspect
@Component
public class Validate { @Pointcut("execution(* com.itdoc.spring.aop.circular.*.*(..))")
public void declareJointPointExpression() {} /**
* 同包引入可以不写包名, 若是不同包引用需要引入包名。
*/
@Before("com.itdoc.spring.aop.circular.Validate.declareJointPointExpression()")
public void beforeValidate() {
System.out.println("I am Validate's beforeValidate method...");
}
}
05-22 09:10