为什么在Spring中使用Ehcache时不能在静态方法中使用@Cacheable?

6

我刚开始接触Spring,读到了不能在静态方法中使用@Cacheable,但是不知道原因。请问有人能够解释一下,让初学者更容易理解吗?

我们可以使用静态方法来检索数据库表吗?

我已经将所有DAO服务层的方法都改成了静态方法,那么这样做是线程安全的吗?


你可能会在这个问题报告中找到答案:https://code.google.com/p/ehcache-spring-annotations/issues/detail?id=51。引用链接中的内容:“静态方法无法被缓存。Spring 中方面的工作方式是通过向注释类添加包装器类(代理)来实现的。在 Java 中,无法向静态方法添加包装器。” - Ceiling Gecko
@CeilingGecko,我已经浏览了那个网站,但是我没有理解,所以您能详细说明一下“Spring框架中Aspect的工作方式是通过为注释类添加包装类(代理)来实现的。在Java中,无法为静态方法添加包装器。”的含义吗? - Kamlesh Kanazariya
我会尝试找到一本Spring书中的漂亮图形,并写出一个答案,如果没有人比我更快的话:P - Ceiling Gecko
2个回答

15

Spring Aspect Concept

就我的评论进行详述:

"静态方法无法被缓存。 Spring中方面的工作方式是通过向注释类添加包装器类(代理)来实现的。在Java中,没有办法对静态方法添加包装器。"

由于Spring需要一个对象来包装以拦截对该对象的调用并在将修改后的输入委托给原始对象之前执行各种操作(从而使Spring方面成为可能)。

由于任何static内容都无法实例化为对象,因此Spring无法包装它并拦截其调用(至少在当前的Spring实现中不行)。


@CellingGecko,非常感谢您,但仍然有一个问题,为什么Spring不能调用包装类中的静态方法(可能是因为“静态方法无法被覆盖”?)。 - Kamlesh Kanazariya
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ceiling Gecko

4

这是提供缓存的机制所存在的限制。

当您将某些方法标记为@Cacheable时,Spring将创建一个代理来拦截方法调用并提供缓存,并将注入该代理而不是原始bean。因此,如果您有以下代码:

@Inject
private MyBean myBean;
...
myBean.myMethod("foo");

如果MyBean声明了myMethod()@Cacheable,那么myBean将不会指向您在应用程序上下文中放置的内容,而是指向一个代理,该代理将执行缓存并仅在缓存查找未返回任何内容时调用原始的MyBean.myMethod()

代理无法拦截静态方法,因此代理无法缓存静态方法。这就是为什么@Cacheable在静态方法上不起作用的原因。


啊,讲解得很好。 - Tibin

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