接口方法上的缓存注解

14

假设我有Spring Data存储库并在findAll方法上放置Cacheable注释:

@Repository
@CacheConfig(cacheNames = TEMPLATE_CACHE)
public interface TemplateRepository extends JpaRepository<Template, Long> {
    @Override
    @Cacheable
    List<Template> findAll();
}

Intellij IDEA 显示警告:

Spring Team recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces. 
You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. 
The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"),
then the caching settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a caching proxy, which would be decidedly bad.

真的那么糟糕吗?

从实际角度来看,会发生什么事情?

如果我想在例如Controller映射中调用findAll,我应该把注释放在哪里?

Spring Data 如何处理这个问题? 对我来说它似乎运行得很好。


最糟糕的情况是没有缓存。但据我所知,只要没有人创建接口的实现并删除@Repository注释,Spring框架就会选择正确的代理方式。我不确定这一点,所以这只是一个评论,而不是答案。 - Martin Baumgartner
1
在一个标准的项目设置中,通常会有一个服务层。控制器 > 服务 > 存储库,即控制器从不直接调用存储库,因此在这种情况下,您可以在服务层缓存。 - Alan Hay
我在我的项目中采用 https://en.wikipedia.org/wiki/Domain-driven_design,术语“Service”指的是与典型的Controller > Service > Repository不同的东西(更加过程化而非面向对象)。因此,如果我想在聚合类上公开UI,则没有必要使用中间层。 - Patrik Mihalčin
1
这只是一个建议,而不是硬性规定。默认情况下,Spring Data使用基于接口的代理。 - John Blum
1
此外,一个好的服务层应该封装业务逻辑/规则(+操作),而不应该放在控制器或存储库中。它也是设置事务上下文、应用(细粒度)安全性或将(远程)操作组合成逻辑工作单元的逻辑层。存储库通常特定于特定的“数据源”,甚至是结构内部。考虑到这些问题,我认为在服务层进行缓存比在存储库上更有意义。我更喜欢在DAO级别使用底层提供程序的缓存能力。 - John Blum
1个回答

1
正如其他人在这里所说的,最好有一个层来从存储库中获取数据。
在该服务层下,您将添加缓存注释。当您以某种意外的方式执行操作时,您会发现Spring的代理功能无法按预期工作。
据我所知,Cacheable注释依赖于编织才能发挥作用。通过Spring Framework截取您对方法的调用以提供缓存功能。如果没有缓存命中,则它将继续运行该方法。
以下是将Cacheable注释放在正确位置的重要性:您可以在同一类中调用已缓存的方法,但由于编织,实际上不会调用缓存。
Spring无法拦截同一类中的调用。将其放在存储库接口上可能会导致问题,因为Spring通过您正在使用的任何Spring Data包提供具体实现,这就是为什么他们提供了那个警告的原因。
简短的解释: https://ducmanhphan.github.io/2019-02-19-How-Spring-Caching-mechanism-works/ Spring官方提供的详细信息: https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache

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