Spring的@Cacheable不起作用,无法缓存

11

我正在使用Spring 3.2和EhCache 2.9。我已经将一个零参数方法按如下方式进行了注释:

@Cacheable(value="myList", key="#result.method.name")
protected List<MyObject> getMyList() {
   //db query
   //return list of results
}

EhCache 配置:

<cache name="myList"
    statistics="true"
    maxEntriesLocalHeap="1"     
    timeToLiveSeconds="3600">
    <persistence strategy="none" />
</cache> 

我希望将数据库查询结果缓存起来。由于此方法没有参数,因此我选择方法名作为缓存键。

在测试中,每次调用方法时都会访问数据库,我不确定原因。有什么想法吗?


更新

故障排除后,我发现了一些有趣的东西。目前定义缓存的getMyList方法与调用它的类在同一个类中。该方法基本上调用DAO来查询列表。如果我将getMyList移动到另一个类中,该类只充当代理,然后将原始调用者更改为调用此新代理,则缓存起作用。我无法解释原因。有任何建议吗?

3个回答

37

假设你去了动物园。你通过入口一次并支付门票。之后,您可以参观狮子、老虎等动物...因为您已经在进入时付过费了。如果你感到无聊想去另一个动物园,你必须走出来,去下一个动物园,再次付钱。

你的类就像是动物园,你的方法就像是动物们,缓存代理就像是入口。当有人调用你的类时,它会通过缓存一次。当她进入,并调用同一类的另一个方法时,它不会再次通过缓存。只有当你走出去并再次进入时,才会通过缓存。

有一个不好的技巧,你可以使用它来覆盖这个过程,叫做注入自身

public class YourClass {
    @Autowired
    private YourClass instance;

    @Cacheable
    public String method1() {
          // now you go through the cache again
          return instance.method2();
    }

    @Cacheable
    public String method2() {
          return "2";
    }
}

这会导致任何递归问题吗?此外,这会影响应用程序的性能吗? - sachin
仍然有用,这解决了我的问题 +1 - NickDelta

16

@Cacheable不能正常工作最可笑的原因是你在“使用”它

springfox.documentation.annotations.Cacheable

而不是

org.springframework.cache.annotation.Cacheable

请注意,当您尚未拥有正确的依赖关系且您的IDE自动导入时,很容易发生这种情况。


12

Ruben的答案绝对是正确的,但我会补充一些其他可能会让其他人遇到麻烦的事情(就像我遇到的那样)。 注释似乎只适用于public方法。即使它在不同的类中,它也不适用于包保护。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接