如何暂时禁用Spring缓存的缓存

Sim*_*mY4 8 java spring caching ehcache

我有一个带有@Cacheable注释定义的spring bean注释

@Service
public class MyCacheableBeanImpl implements MyCacheableBean {
    @Override
    @Cacheable(value = "cachedData")
    public List<Data> getData() { ... }
}
Run Code Online (Sandbox Code Playgroud)

我需要这个类能够禁用缓存并仅使用来自原始源的数据.这应该基于来自外部的一些事件发生.这是我的方法:

@Service
public class MyCacheableBeanImpl implements MyCacheableBean, ApplicationListener<CacheSwitchEvent> {
    //Field with public getter to use it in Cacheable condition expression
    private boolean cacheEnabled = true;

    @Override
    @Cacheable(value = "cachedData", condition = "#root.target.cacheEnabled") //exression to check whether we want to use cache or not
    public List<Data> getData() { ... }

    @Override
    public void onApplicationEvent(CacheSwitchEvent event) {
        // Updating field from application event. Very schematically just to give you the idea
        this.cacheEnabled = event.isCacheEnabled();
    }

    public boolean isCacheEnabled() {
        return cacheEnabled;
    }

}
Run Code Online (Sandbox Code Playgroud)

我担心的是,这种方法的"魔力"水平非常高.我甚至不确定如何测试这是否可行(基于spring文档,这应该可行,但如何确定).我做得对吗?如果我错了,那该怎么做呢?

小智 5

我在寻找的是NoOpCacheManager:

为了使其工作,我从xml bean创建切换到了工厂

我做了如下的事情:

    @Bean
public CacheManager cacheManager() {
    final CacheManager cacheManager;        
    if (this.methodCacheManager != null) {
        final EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        ehCacheCacheManager.setCacheManager(this.methodCacheManager);
        cacheManager = ehCacheCacheManager;
    } else {
        cacheManager = new NoOpCacheManager();
    }

    return cacheManager;
}
Run Code Online (Sandbox Code Playgroud)

  • 好的。这并不完全是所要求的,因为同样,您仅根据启动条件创建缓存管理器,而我需要在运行时打开和关闭缓存。但这给了我一个想法,我可以创建自己的缓存管理器委托,该委托将根据其中的一些易失性状态在 NoOp 和普通 CacheManager 之间进行选择。这样 Spring 注释将继续工作,我可以控制缓存代理的行为方式。 (2认同)