2014-02-13 50 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