为什么这个Spring AOP切入点没有被触发?

Tao*_*Tao 6 java aop spring

我正在编写非常基于模式的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>
Run Code Online (Sandbox Code Playgroud)

tao.zhang.Listener中的方法scream()只打印出一些文本,并且应该在调用方法callme()时执行.

我有一个名为logger的bean ,它有方法log()和callme()

public void log(){
    callme();
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}

public void callme(){
    System.out.println("I'm called");
}
Run Code Online (Sandbox Code Playgroud)

请注意,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>
Run Code Online (Sandbox Code Playgroud)

奇怪的是,没有调用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>
Run Code Online (Sandbox Code Playgroud)

scream()被调用!

有什么建议?在我看来,这个切入点与另一个方法中调用的方法不匹配......

Don*_*ows 11

Spring AOP仅在通过bean句柄完成调用时捕获方法调用(因为拦截器是通过使用代理对象来应用的),而不是在直接调用方法时.

为了使你的代码工作,你需要切换到使用AspectJ(它通过重写类的字节码,它允许它拦截更多的东西,并更透明地这样做)或改变你调用的方式,callme()以便它通过豆柄:

SomeClass selfRef;

public void log(){
    selfRef.callme();
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}

public void callme(){
    System.out.println("I'm called");
}
Run Code Online (Sandbox Code Playgroud)

您需要selfRef明确配置该字段; 它不会被自动装配.