1. 程式人生 > >Spring AOP: 織入的順序

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將以隨機順序來織入這兩個增強處理,沒有辦法指定它們的織入順序。如果確實需要保證它們以固有的順序被織入,則可考慮將多個增強處理壓縮成一個,或者將不同增強處理重構到不同切面類中,通過在切面類級別上進行排序。