Spring AOP: 织入的顺序
spring AOP 采用和 AspectJ 一样的优先顺序来织入增强处理:在进入连接点时,高优先级的增强处理将先被织入;在退出连接点时,高优先级的增强处理会后被织入。
当不同的切面里的两个增强处理需要在同一个连接点被织入时,Spring AOP将以随机的顺序来织入这两个增强处理。如果应用需要指定不同切面类里增强处理的优先级,Spring提供了如下两种解决方案:
① 让切面类实现org.springframework.core.Ordered接口,实现该接口只需实现一个int getOrder( )方法,该方法返回值越小,则优先级越高。
② 直接使用@Order注解来修饰一个切面类,使用 @Order 时可指定一个int型的value属性,该属性值越小,则优先级越高。
Person.Java :
- public interface Person {
- public void eat(String food);
- }
Chinese.java :
- @Component
- public class Chinese implements Person {
- @Override
- public void eat(String food) {
- System.out.println("我正在吃:"+food);
- }
- }
AspectFirst.java :
- import org.aspectj.lang.annotation.After;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.springframework.core.annotation.Order;
- @Aspect
- @Order(5)
- public class AspectFirst {
- @Before("execution(* com.bean.*.*(..))")
- public void aspectFirstStart(){
- System.out.println("@Before增强处理:我是AspectFirst切面,我的优先级为5");
- }
- @After("execution(* com.bean.*.*(..))")
- public void aspectFirstEnd(){
- System.out.println("@After增强处理:我是AspectFirst切面,我的优先级为5");
- }
- }
AspectSecond.java :
- import org.aspectj.lang.annotation.After;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.springframework.core.annotation.Order;
- @Aspect
- @Order(1)
- public class AspectSecond {
- @Before("execution(* com.bean.*.*(..))")
- public void aspectSecondStart(){
- System.out.println("@Before增强处理:我是AspectSecond切面,我的优先级为1");
- }
- @After("execution(* com.bean.*.*(..))")
- public void aspectSecondEnd(){
- System.out.println("@After增强处理:我是AspectSecond切面,我的优先级为1");
- }
- }
bean.xml :
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
- <context:component-scan base-package="com.bean">
- <context:include-filter type="annotation"
- expression="org.aspectj.lang.annotation.Aspect"/>
- </context:component-scan>
- <aop:aspectj-autoproxy/>
- </beans>
Test.java :
- public class Test {
- public static void main(String[] args) {
- ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
- Person p=(Person) ctx.getBean("chinese");
- p.eat("西瓜");
- }
- }
运行程序,控制台输出:
同一个切面类里的两个相同类型的增强处理在同一个连接点被织入时,Spring AOP将以随机顺序来织入这两个增强处理,没有办法指定它们的织入顺序。如果确实需要保证它们以固有的顺序被织入,则可考虑将多个增强处理压缩成一个,或者将不同增强处理重构到不同切面类中,通过在切面类级别上进行排序。