I’m writing very basic schema-based Spring AOP, here’s the .xml
<bean id="aoplistener" class="tao.zhang.Listener"/>
<aop:config>
<aop:aspect ref="aoplistener">
<aop:pointcut id="whenCalled" expression="execution(* callme(..))" />
<aop:after method="scream" pointcut-ref="whenCalled" />
</aop:aspect>
</aop:config>
The method scream() in tao.zhang.Listener just prints out some text, and is supposed to be executed whenever a method callme() is called.
I have a bean called logger which has the methods log() and callme()
public void log(){
callme();
System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}
public void callme(){
System.out.println("I'm called");
}
Note that callme() is called by log()
Now I have a scheduler which calls log() every 5 seconds:
<task:scheduler id="myScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="logger" method="log" fixed-rate="5000"/>
</task:scheduled-tasks>
Strangely, scream() is not invoked, but if callme() is called directly:
<task:scheduler id="myScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="logger" method="callme" fixed-rate="5000"/>
</task:scheduled-tasks>
scream() is invoked!
Any suggestions? It seems to me that this pointcut doesn’t match methods called inside another method …
Spring AOP only traps a method call when the call is done through a bean handle (because the interceptor is applied through the use of a proxy object) and not when the method is called directly.
To make your code work, you need to either switch to using AspectJ (which works by rewriting the class’s bytecode, which allows it to intercept far more things and to do so more transparently) or to change how you call
callme()so that it is via a bean handle:You need to configure the
selfReffield explicitly; it won’t be autowired.