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 ...
In Spring AOP, a join point always represents a method execution. A pointcut is a predicate that matches the join points, and the pointcut expression language is a way of describing pointcuts programmatically.
For using Spring AOP in Spring beans, we need to do the following: Declare AOP namespace like xmlns:aop=“https://www.springframework.org/schema/aop” Add aop:aspectj-autoproxy element to enable Spring AspectJ support with auto proxy at runtime. Configure Aspect classes as other Spring beans.
AspectJ provides primitive pointcuts that capture join points at these times. These pointcuts use the dynamic types of their objects to pick out join points. They may also be used to expose the objects used for discrimination. this(Type or Id) target(Type or Id)
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:
SomeClass selfRef;
public void log(){
selfRef.callme();
System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}
public void callme(){
System.out.println("I'm called");
}
You need to configure the selfRef
field explicitly; it won't be autowired.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With