【问题标题】:Spring Boot disable @Cacheable per requestSpring Boot 根据请求禁用 @Cacheable
【发布时间】:2017-05-19 21:30:39
【问题描述】:

我正在尝试基于 URL 参数禁用 Spring Boot 中的 Cacheable 函数。例如http://myapplication.com/some/request?cache=false

我尝试了 SpEL 的条件,但我无法让它工作

@Cacheable(value = "value", keyGenerator = "keygenerator", condition = "#{someComponent.isCacheEnabled()}")

有什么建议吗?提前致谢!

【问题讨论】:

  • someComponent 是什么?
  • 我猜 someComponent 将是知道 url 参数的 bean,正如@john-blum 在下面建议的那样

标签: java spring caching spring-boot spring-cache


【解决方案1】:

user4843-

我假设你的“任意组件”(即someComponent)是你的SpringApplicationContext中的一个Spring托管bean?

如果是这样,那么您没有使用在@Cacheable 注释声明中的condition 属性上指定的SpEL 表达式正确引用此Spring 托管bean。它应该是……

condition="#{@someComponent.isCacheEnabled()}"

注意someComponent@ 符号的使用,在here 中有更详细的解释。而且,虽然 Spring documentation 对此事不太清楚,但它确实暗示了在处理缓存注释使用时在 Spring 的缓存抽象 中创建和使用的 SpEL 评估上下文除了表 36.1 - 缓存 SpEL 可用元数据 中列出的参数之外,“内置参数”或 SpEL conventions。查看示例here

我还要提醒您不要使用一些任意组件,或 Spring 托管 bean 来管理整个应用程序的缓存状态,就像这样。

  1. 首先,如果 someComponent 是一个 Singleton bean(Spring 容器中的默认值),那么这个 bean 需要是线程安全的,尤其是因为它的状态正在发生变化,可能而且似乎随着每个 HTTP 请求而变化,这导致我......

  2. 如果缓存状态取决于每个单独的 HTTP 请求,我不确定您是否需要 Spring 托管 bean 来管理应用程序服务/存储库方法的“可缓存状态”,特别是因为大多数 HTTP 容器在单独的线程中处理每个 HTTP 请求。你肯定会遇到竞争条件。在这种情况下,我宁愿使用额外的可缓存服务方法参数来确定源自 HTTP 请求的特定服务方法调用的可缓存状态。

例子:

@Cacheable(value = "value", keyGenerator="keyGenerator" conditional="#enableCaching")
public <return-type> someCacheableServiceMethod(..., boolean enableCaching) {
  ...
}

事实上,我什至建议使用更易于理解的面向业务的规则来确定服务方法的可缓存状态。

希望这会有所帮助!

-约翰

【讨论】:

  • 谢谢!我会试试这个。请注意,我禁用缓存的用例适用于使用 api 的开发人员,他们希望确保从数据源(在本例中为 Postgres)中提取数据。有人可能会说这是一种“黑客行为”
猜你喜欢
  • 2021-01-09
  • 2019-05-27
  • 2016-06-25
  • 1970-01-01
  • 2012-06-10
  • 2018-03-17
  • 2018-02-07
  • 1970-01-01
  • 2021-07-25
相关资源
最近更新 更多