Spring AOP建议没有被调用

时间:2013-06-03 13:18:45

标签: java aspectj spring-aop

我的建议是不要通过此方法调用方法 getPOInvoice 方法,但如果我单独调用它,则会调用通知并且 getPOInvoice getPOInvoice < / strong>在同一类中声明。

public StreamingOutput getPDFStream(String invoiceId, String versionNumber) throws TugnavException {

   final POInvoice poInv =  getPOInvoice(invoiceId, versionNumber);
   ...
}

我的建议是:

@AfterReturning(value="execution(* com.tugnav.service.facade.*.get*(..))", returning="doc")
    public TugnavBaseDocument setupTimeCreatedString(TugnavBaseDocument doc){
    ...

}

如果我从另一个类调用此方法,则会调用通知。

为什么不在内部调用?

3 个答案:

答案 0 :(得分:3)

您需要阅读有关proxies here

的文档

基本上,由于生成代理的方式,另一个实例方法中的实例方法调用不会触发方面(或代理行为)。

假设:

class FooBar {
    // advised method
    public void foo() {
        bar();
    }

    // would've been advised
    public void bar() {
        // ... do something
    }
}

假设FooBar的实例已被代理,对foo()的调用将触发该方面,因为从外部您可以引用代理对象。当您在内部调用bar()时,您可以访问this(相当于this.bar()),这是对目标实例(实际对象)的引用,因此没有添加行为。

有几种方法可以解决这个问题,但可能不是你想要的方式。请参阅this问题的答案。

答案 1 :(得分:0)

AOP通常不会这样工作。

通过Proxies将AOP作为一个方面添加到已编译的类中,因此它对内部类调用没有任何影响。

  1. 当它是外部校准时,你实际上是指某个代理人拦截你的电话并触发适当的AOP电话。
  2. 当它是内部校准时,在课堂内,它是直接呼叫,不涉及任何代理。
  3. 作为解决方案,您可以执行以下操作:

    1. 您正在使用的重构服务,以排除内部呼叫
    2. 使用您的AOP功能更改类加载时的字节码:)

答案 2 :(得分:0)

如果你想从getPDFStream(..)方法调用getProDvStream(..)时调用getPOInvoice方法,在同一个bean中,你不能使用基于代理的AOP,比如Spring默认使用。相反,您应该使用AspectJ加载时间编织(LTW)。

http://static.springsource.org/spring/docs/3.2.2.RELEASE/spring-framework-reference/html/aop.html#aop-aj-ltw