Spring AOP 不适用于@CachePut 等自调用

Spring AOP does not work with self-invocation such as @CachePut

我正在研究 Spring 缓存注释,但我发现其中发生了一些奇怪的事情。

假设我在同一个服务 class 中调用一个方法,其中有 @CachePut 注释。那没有被缓存。

如果我将该方法移至其他某个服务实现文件并调用该方法,缓存将起作用。

我需要知道我做错了什么。

假设你写下面的 class 和 @CachePut ,

public class FooBean implements Foo{

    @CachePut
    public String doSomething(){

    }
}

Spring 幕后将创建一个包装您的 class 的 AOP 代理,以便它可以在调用实际的 @CachePut 方法之前或之后应用一些缓存魔法代码。您可以认为 AOP 代理看起来像:

public class FooBeanProxy implements Foo{

    private FooBean fooBean;

    public String doSomething(){

        //Maybe there are some caching magic codes here....
        fooBean.doSomething()
        //Maybe there are other caching magic codes here........
    }
}

If i move that method to some other service implementation file and calling that method caching is working.

假设您执行以下操作以调用 @CachePut 方法:

@Component
public class App {

    //FooBeanProxy actually injected HERE
    @Autowired
    private Foo foo;

    public void startDoing(){
        foo.doSomething();
    }
}

Spring 为您注入的是 FooBeanProxy,而不是您的 FooBean。因此,当您调用该 @CachePut 方法时,缓存魔术代码将 运行 正如您调用 FooBeanProxy

Say I am calling a method in the same service class that has @CachePut annotation in it. That is not getting cached.

也就是说是自调用。您正在调用的是 this reference ,这是您的 FooBean 实例,但不再是 FooBeanProxy 实例。所以那些缓存魔术永远不会被执行,因此结果不会被缓存。

其实我上面说的在docs. If you still want to have @CachePut to take effect in the self-invocation case , you can use the horrible and ugly AopContext.currentProxy() solution mentioned in the docs里面已经提到了或者用AspectJ