我正在编写非常基于模式的Spring AOP,这里是.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>
tao.zhang.Listener中的方法 scream()只打印出一些文本,,并且应该在调用方法callme()时执行。 < / p>
我有一个名为 logger 的bean,它有方法log()和callme()
public void log(){
callme();
System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}
public void callme(){
System.out.println("I'm called");
}
请注意,callme()由log()
调用现在我有一个调度程序,每隔5秒调用一次log():
<task:scheduler id="myScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="logger" method="log" fixed-rate="5000"/>
</task:scheduled-tasks>
奇怪的是, scream()未被调用,但是如果直接调用callme():
<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()被调用!
有什么建议吗?在我看来,这个切入点与另一个方法中调用的方法不匹配...
答案 0 :(得分:10)
Spring AOP仅在通过bean句柄完成调用时捕获方法调用(因为拦截器是通过使用代理对象来应用的),而不是直接调用方法时。
要使代码正常工作,您需要切换到使用AspectJ(通过重写类的字节码,它允许它拦截更多的东西并更透明地执行)或改变你的方式调用callme()
以便它通过bean句柄:
SomeClass selfRef;
public void log(){
selfRef.callme();
System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}
public void callme(){
System.out.println("I'm called");
}
您需要明确配置selfRef
字段;它赢得自动装配。