Java 为什么这个春季AOP切入点没有被触发?

Java 为什么这个春季AOP切入点没有被触发?,java,spring,aop,Java,Spring,Aop,我正在编写非常基本的基于模式的SpringAOP,下面是.xml tao.zhang.Listener中的方法cream()只是打印出一些文本,,并且应该在调用方法callme()时执行。 我有一个名为logger的bean,它有log()和callme()方法 公共作废日志(){ callme(); System.out.println(“你好,来自记录器”~~~~~~~~~~~~~~~~~~~~~~~”; } public void callme(){ System.out.printl

我正在编写非常基本的基于模式的SpringAOP,下面是.xml


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

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

公共作废日志(){
callme();
System.out.println(“你好,来自记录器”~~~~~~~~~~~~~~~~~~~~~~~”;
}
public void callme(){
System.out.println(“我被叫”);
}
注意,callme()由log()调用

现在我有了一个每5秒调用log()的计划程序:


奇怪的是,cream()没有被调用,但是如果直接调用callme():


尖叫()被调用


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

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
字段;它不会自动连线。

是的,非常感谢!我刚刚仔细阅读了spring手册中的这句话:
SpringAOP只支持Springbeans的方法执行连接点
我发现了解spring是如何工作的对我帮助很大。如果它做了任何花哨的事情(包括AOP),它会给您一个代理对象,其中包含它所需要的拦截点。代理对象——bean句柄,如果你愿意的话——是你应该如何对bean进行所有调用的,你不应该通过
this
调用Spring(这就是原始
callme()
所做的;
this.
是隐式的)。我现在觉得Spring AOP在很多情况下几乎没有用处。在我当前的项目中,每当调用
callme()
并且
callme()
被这个类中的各种方法用作子例程时,我都想记录一些日志,这是一种非常常见的情况。@Tao:嗯,您的选择是重构成两个(或更多)bean,通过自句柄技巧调用,或者使用AspectJ进行拦截在我的代码中,我主要通过重构来处理事情,我也使用了一些自我技巧,但我避免使用AspectJ,因为我已经有了其他字节码重写系统,不想让整个系统运行得很好。(已经够复杂了!)