1
votes

My advice is not getting called for method getPOInvoice method from this method, but if I call it separately then advice is getting called and getPOInvoice and getPOInvoice is declared in same class.

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

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

My advice is:

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

}

If I call this method from another class then advice is getting called.

Why is it not getting called internally?

3

3 Answers

3
votes

You need to read the documentation about proxies here.

Basically, because of the way proxies are generated, a instance method call within another instance method will not trigger an aspect (or proxy behavior).

Given:

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

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

Say an instance of FooBar was proxied, a call to foo() will trigger the aspect because from outside you have a reference to the proxy object. When you call bar() internally, you have access to this (equivalent to this.bar()) which is a reference to the target instance, the actual object, so there is no added behavior.

There are a few ways to solve this problem, but probably not the way you want. See the answer to this question.

0
votes

AOP would not normally work this way.

AOP is added as an aspect through Proxies, to compiled class, so it does not have any effect on the internal class invocations.

  1. When it's an outer cal, you are actually referring to some Proxy which intercepts your call and triggers appropriate AOP calls.
  2. When it's internal cal, inside the class, it is a direct call, without any Proxy involved.

As a solution you can do following:

  1. Refactore service you are using, to exclude internal calls
  2. Alter bytecode on Class loading, with your AOP functionality :)
0
votes

If you want that your advice is called for getPOInvoice method when you are invoking from method getPDFStream(..), both in the same bean, you can't use a proxy-based AOP, like Spring use by default. Instead you should use load time weaving(LTW) with AspectJ.

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