问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/10774946/pointcut-confusion-with-inheritance