我打算使用Spring @Cacheable注释来缓存调用方法的结果 .
但是这种实现在某种程度上对我来说并不是非常“安全” . 据我所知,返回的值将由底层缓存引擎缓存,并在调用Spring evict方法时删除 .
我需要一个实现,它不会破坏旧值,直到加载新值 . 这是必需的,以下方案应该有效:
-
调用Cacheable方法 - >返回有效结果
-
结果将由Spring @Cacheable后端缓存
-
Spring使缓存失效,因为它已过期(例如1小时的TTL)
-
再次调用Cacheable方法 - >返回异常/ null值!
-
OLD结果将再次缓存,因此,该方法的未来调用将返回有效结果
这怎么可能?
2 回答
如果@Cacheable方法抛出异常,则可以通过对Google Guava的最小扩展轻松实现您对旧值的服务要求 .
使用以下示例配置
CacheKey用于公开SimpleKey属性的单一目的 . Guavas refreshAfterWrite将配置刷新时间而不会使缓存条目到期 . 如果使用@Cacheable注释的方法抛出异常,则缓存将继续提供旧值,直到由于maximumSize被驱逐或被成功方法响应中的新值替换 . 您可以将refreshAfterWrite与expireAfterAccess和expireAfterAccess结合使用 .
我在阅读Spring代码时可能是错的,尤其是
org.springframework.cache.interceptor.CacheAspectSupport#execute(org.springframework.cache.interceptor.CacheOperationInvoker, org.springframework.cache.interceptor.CacheAspectSupport.CacheOperationContexts)
,但我相信抽象并没有提供你所要求的 .Spring不会使条目到期,这将留给底层的缓存实现 .
您提到即使它们已过期您也希望看到值 . 这与我所知道的大多数缓存实现中使用的到期抽象相反 .
返回先前缓存的调用错误值显然是特定于用例的 . Spring抽象将简单地将错误抛回用户 .
CacheErrorHandler
机制仅处理与缓存调用相关的异常 .总而言之,在我看来,你要求的是非常具体的用例,因此不是抽象将/应该提供的东西 .