Question

I am confused by writing a pointcut that matches all executions of a method. I tried the pointcut that should match all method-executions of class Alpha:

execution(* Alpha.*(..))

with the following class-hierachy

public class Alpha {
    public void alphaMethod() {...}
}
public class Beta extends Alpha {
    public void betaMethod() {
        alphaMethod();
    }
}

If the Main-program calls alphaMethod on an Beta-instance my advice is called like expected but the Main-program calls betaMethod that also calls alphaMethod inside my advice is not called and I don't understand why.

Aspect-Definition:

@Aspect
public class MyAspect {
    @Before(value = "execution(* Alpha.*(..))", argNames="joinPoint")
    public void myAdvice(JoinPoint joinPoint) {
        System.out.println("BEFORE: " + joinPoint.getSignature());
    }
}

Main-method:

Beta beta = ...;
beta.alphaMethod(); //advice is called
beta.betaMethod(); //advice is NOT called.
Was it helpful?

Solution

This is expected.

Spring AOP uses proxy classes to wrap advised beans. When you call alphaMethod() from within a Beta method, the proxy isn't even aware of it.

See this answer for more information.

OTHER TIPS

The reason, as already answered, is clear. You can fix this by employing load-time weaving instead of proxying (I guess it comes down to a config option somewhere and a dependency to AspectJ, if not already depending on it) or injecting the bean to itself as a dependency and then implementing

public void betaMethod() {
    selfBean.alphaMethod();
}

This will work because selfBean is not the same reference as this, the former being a reference to the proxy, the latter a reference to the original, proxied object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top