2014-02-13 64 views
1

我在Spring AOP是新的,這是我的代碼進行測試:Spring AOP的執行順序

目標內com.kk.entity包:

@Component 
public class AopTargetOne { 
    private String name; 
    private String password; 
    private String email; 
    private String address; 

    //getter and setters omitted 
} 

@Component 
public class AopTargetSecond { 
    private String name; 
    private int age; 
    private String email; 
    //getter and setters omitted 
} 

看點:

@Component 
@Aspect 
public class VariableCheckAspect { 

    //intercept all the setter methods 
    @Pointcut("execution(* com.kk.entity.*.set*(..))") 
    private void aopIsSetMethod() { 

    } 

    @Before("com.kk.aop.VariableCheckAspect.aopIsSetMethod() && args(val,..)") 
    public void checkSetValue(JoinPoint joinpoint, String val) { 
     System.err.println("******** Start check set value with method *********** " + joinpoint.getSignature()); 
     System.out.println("value is:" + val); 
     System.err.println("******** End ****"); 
    } 
} 

應用:

AopTargetOne ah = context.getBean(AopTargetOne.class); 
    ah.setAddress("aopholder address"); 
    ah.setEmail("aopholder email"); 
    ah.setName("aopholder name"); 

    AopTargetSecond ak = (AopTargetSecond) context.getBean("aopTargetSecond"); 
    ak.setName("aopkepper name"); 
    ak.setEmail("aopkepper email"); 
    ak.setAge(23); 

我得到了輸出:

******** Start check set value with method *********** void com.kk.entity.AopTargetOne.setAddress(String) 
******** End **** 
value is:aopTargetOne address 
******** Start check set value with method *********** void com.kk.entity.AopTargetOne.setEmail(String) 
******** End **** 
******** Start check set value with method *********** void com.kk.entity.AopTargetOne.setName(String) 
******** End **** 
******** Start check set value with method *********** void com.kk.entity.AopTargetTwo.setName(String) 
******** End **** 
value is:aopTargetOne email 
value is:aopTargetOne name 
value is:aopTargetTwo name 
******** Start check set value with method *********** void com.kk.entity.AopTargetTwo.setEmail(String) 
******** End **** 
value is:aopTargetTwo email 

這讓我困惑!看起來代碼不能以正常順序運行。

雖然我希望像這樣的輸出:

******** Start check set value with method *********** void com.kk.entity.AopTargetOne.setAddress(String) 
value is:aopTargetOne address 
******** End **** 
******** Start check set value with method *********** void com.kk.entity.AopTargetOne.setEmail(String) 
value is:aopTargetOne email 
******** End **** 
.... 

什麼問題?有任何解決這個問題的方法嗎?

回答

1

這只是您在兩個不同的輸出流上執行輸出的結果。您正在寫入erroutThese don't necessarily get flushed in the same order (between streams).

System.err.println(..); 
System.out.println(..); 

寫入相同OutputStream,你會看到你的預期輸出。

如果我們刪除包含恆星的輸出,我們得到

value is:aopTargetOne address 
value is:aopTargetOne email 
value is:aopTargetOne name 
value is:aopTargetTwo name 
value is:aopTargetTwo email 

這是您設置的確切順序。

+0

也可以使用System.out.flush()和System.err.flush() –

+0

進行刷新OMG !!!!!!爲什麼我會犯這樣一個愚蠢的錯誤!謝謝,它有效。 – hguser