Spring AOP不适用于@CachePut之类的自调用

时间:2019-01-19 07:36:12

标签: spring spring-boot aop

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

说我要在同一服务类中调用带有@CachePut批注的方法。不会被缓存。

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

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

1 个答案:

答案 0 :(得分:1)

假设您使用@CachePut

编写以下类
public class FooBean implements Foo{

    @CachePut
    public String doSomething(){

    }
}

在后台运行Spring将创建一个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........
    }
}
  

如果我将该方法移至其他服务实现文件,并且   调用该方法可以正常工作。

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

@Component
public class App {

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

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

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

时运行
  

说我正在具有@CachePut的同一服务类中调用方法   其中的注释。不会被缓存。

这意味着它是自我调用。您要调用的是 this 参考,它是您的FooBean实例,但现在不再是FooBeanProxy。因此,这些缓存魔术将永远不会执行,因此结果将不会被缓存。

实际上,我在docs中已经提到了我上面所说的内容。如果您仍然希望@CachePut在自调用的情况下生效,则可以使用docs中提到的可怕而丑陋的AopContext.currentProxy()解决方案,也可以使用AspectJ