如何在@CacheEvict中调用侦听器或拦截器

时间:2017-12-13 17:54:16

标签: spring-mvc spring-boot spring-data spring-cache

我需要在调用@CacheEvict时调用某些功能。有没有办法在Spring @CacheEvict中调用侦听器或拦截器?

2 个答案:

答案 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.evic‌​t(..))

此表达式将您的AOP Aspect与ConcurrentMapCache"提供商", Spring的缓存抽象(以及 Spring Boot中的默认值)联系起来)。

使用Ehcache,Hazelcast,Redis,GemFire / Geode或这些"提供商"的多种组合时会发生什么?在你的申请中?

相反,你可以稍微调整一下AOP切入点表达式......

execution(* org.springframework.cache.Cache.evic‌​t(..))

here。这是安全的,因为所有"缓存提供商"必须提供两件事:CacheManager实现和应用程序中指定的每个缓存的Cache实现。同样,Cache接口是"适配器"到后盾商店。再次,see the docs了解更多详情。

任何一种方法都需要权衡。特定于提供商的解决方案通常会提供更多控制功能,但使用AOP方法更具可重用性。做适合你UC的事情。

希望这有帮助。

干杯! -John

答案 1 :(得分:0)

John的答案是正确的,但重要的是要知道Cache类不是Spring托管的bean,而CacheManager是。

由于这个原因,您必须引入其他AspectJ依赖项,并进行某种编译或后编译编织才能定位到Cache.evict方法。