我需要在调用@CacheEvict时调用某些功能。有没有办法在Spring @CacheEvict中调用侦听器或拦截器?
答案 0 :(得分:1)
通常情况下,这是非常快速的提供商"因为没有2个缓存提供商具有相同的功能。
例如,我主要使用内存数据网格(IMDG)技术,如Pivotal GemFire和OSS版本Apache Geode。两者中的used as a "caching provider"都可以是Spring's Cache Abstraction。使用GemFire / Geode,您可以在GemFire / Geode o.a.g.cache.CacheListener
(基本上是java.util.Map
)上注册Region
回调,backing Spring Cache
接口,并在 Spring的缓存基础架构中用作"适配器"到后盾商店。正如您在SD GemFire / Geode提供程序实现中所看到的那样,"eviction" triggers是GemFire / Geode Region.remove(key)
。随后可以使用Region's
已注册的CacheListener.afterDestroy(:EntryEvent)回调方法捕获和处理此驱逐。
但是,这只是处理应用程序驱逐通知的一种方法。
当然,正如 @Borino 指出的那样,你可以利用 Spring的 AOP支持来拦截"拦截"缓存逐出操作。这种方法的优点是它在不同的缓存提供程序中更通用且可重用。
虽然,我会说你不应该根据基础"缓存提供商"开发一个AOP切入点表达式,因为 @Borino 指示,即...
execution(* org.springframework.cache.concurrent.ConcurrentMapCache.evict(..))
此表达式将您的AOP Aspect与ConcurrentMapCache
"提供商", Spring的缓存抽象(以及 Spring Boot中的默认值)联系起来)。
使用Ehcache,Hazelcast,Redis,GemFire / Geode或这些"提供商"的多种组合时会发生什么?在你的申请中?
相反,你可以稍微调整一下AOP切入点表达式......
execution(* org.springframework.cache.Cache.evict(..))
见here。这是安全的,因为所有"缓存提供商"必须提供两件事:CacheManager
实现和应用程序中指定的每个缓存的Cache
实现。同样,Cache
接口是"适配器"到后盾商店。再次,see the docs了解更多详情。
任何一种方法都需要权衡。特定于提供商的解决方案通常会提供更多控制功能,但使用AOP方法更具可重用性。做适合你UC的事情。
希望这有帮助。
干杯! -John
答案 1 :(得分:0)
John的答案是正确的,但重要的是要知道Cache类不是Spring托管的bean,而CacheManager是。
由于这个原因,您必须引入其他AspectJ依赖项,并进行某种编译或后编译编织才能定位到Cache.evict方法。