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

时间:2016-03-10 09:23:39

标签: java spring caching ehcache

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

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

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

@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;
    }

}

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

2 个答案:

答案 0 :(得分:3)

我在寻找的是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;
}

答案 1 :(得分:1)

受 SimY4 最后一条评论的启发,这里是我的工作解决方案,重载 file.seek(0) 以提供运行时切换。 只需使用 SimpleCacheManager 即可关闭/开启。

switchableSimpleCacheManager.setEnabeld(false/true)

}

配置(使用咖啡因):

package ch.hcuge.dpi.lab.cache;

import org.springframework.cache.Cache;
import org.springframework.cache.support.NoOpCache;
import org.springframework.cache.support.SimpleCacheManager;

/**
* Extends {@link SimpleCacheManager} to allow to disable caching at runtime
*/
public class SwitchableSimpleCacheManager extends SimpleCacheManager {

  private boolean enabled = true;

  public boolean isEnabled() {
      return enabled;
  }

/**
 * If the enabled value changes, all caches are cleared
 *
 * @param enabled true or false
 */
public void setEnabled(boolean enabled) {
    if (enabled != this.enabled) {
        clearCaches();
    }
    this.enabled = enabled;
}

@Override
public Cache getCache(String name) {
    if (enabled) {
        return super.getCache(name);
    } else {
        return new NoOpCache(name);
    }
}

protected void clearCaches() {
    this.loadCaches().forEach(cache -> cache.clear());
}