我有一个带有@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文档,这应该可行,但如何确定)。我做得对吗?如果我错了,那该怎么做呢?
答案 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());
}