前面博客中已经介绍切面的使用方法,但是都是介绍的只有一个切面类的情况,如果同时存在多个切面的话,多个切面之间的执行顺序如何设置呢?示例如下
一、多个切面,无优先级设置
首先建立一个目标接口ArithmeticCalculator:
package lzj.com.spring.aop;
public interface ArithmeticCalculator {
int add(int i, int j);
}
然后创建接口的实现类ArithmeticCalculatorIml :
package lzj.com.spring.aop;
import org.springframework.stereotype.Component;
@Component("arithmeticCalculator")
public class ArithmeticCalculatorIml implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
int result = i + j;
System.out.println("add->result:" + result);
return result;
}
}
当执行目标类中的方法时,希望先执行两个切面中的方法,定义两个切面LogProxy和ThirdMethod:
LogProxy类:
package lzj.com.spring.aop;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogProxy {
@Before("execution(public int lzj.com.spring.aop.ArithmeticCalculator.*(int, int))")
public void beforMethod(JoinPoint point){
String methodName = point.getSignature().getName();
System.out.println("LogProxy切面>目标方法为" + methodName);
}
}
ThirdMethod类:
package lzj.com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class ThirdMethod {
@Before("execution(public int lzj.com.spring.aop.ArithmeticCalculator.*(int, int))")
public void getInfo(JoinPoint joint){
String methodName = joint.getSignature().getName();
System.out.println("ThirdMethod切面>目标方法" + methodName);
}
}
配置bean-aop.xml配置文件,用来定义扫描的范围和激活切面注解@Aspect
<context:component-scan base-package="lzj.com.spring.aop"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
创建测试方法如下:
package lzj.com.spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-aop.xml");
ArithmeticCalculator arithmetic = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
arithmetic.add(3, 2);
}
}
执行测试方法,输出结果如下:
LogProxy切面>目标方法为add
ThirdMethod切面>目标方法add
add->result:5
当没有定义切面优先级时,输出会随机选择,输出中显示先执行的LogProxy中的切面方法,后执行的ThirdMethod中的方法。如果我们制定切面的优先级,先执行ThirdMethod中的切面方法,然后执行LogProxy中的切面方法。
二、多个切面,有优先级设置
LogProxy和ThirdMethod两个切面分别用@Order注解标识,@Order中的值越小,优先级越高。
LogProxy切面:
package lzj.com.spring.aop;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/*该切面优先级低,后执行*/
@Order(2)
@Aspect
@Component
public class LogProxy {
@Before("execution(public int lzj.com.spring.aop.ArithmeticCalculator.*(int, int))")
public void beforMethod(JoinPoint point){
String methodName = point.getSignature().getName();
System.out.println("LogProxy切面>目标方法为" + methodName);
}
}
ThirdMethod切面:
package lzj.com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/*该切面的优先级最高,先执行*/
@Order(1)
@Component
@Aspect
public class ThirdMethod {
@Before("execution(public int lzj.com.spring.aop.ArithmeticCalculator.*(int, int))")
public void getInfo(JoinPoint joint){
String methodName = joint.getSignature().getName();
System.out.println("ThirdMethod切面>目标方法" + methodName);
}
}
执行测试方法,输出结果如下:
ThirdMethod切面>目标方法add
LogProxy切面>目标方法为add
add->result:5
发现优先级高的切面ThirdMethod先执行,优先级低的切面LogProxy后执行。