Domanda

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.
È stato utile?

Soluzione

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top