Java 自定义缓存解析程序不工作
我有一个Spring Boot项目,其中有一个自定义的Java 自定义缓存解析程序不工作,java,spring,spring-cache,Java,Spring,Spring Cache,我有一个Spring Boot项目,其中有一个自定义的CacheResolver,因为我需要在运行时决定要使用哪个缓存,我没有任何编译错误,但是,当我做一些测试并在自定义的CacheResolver上放置断点时,它永远不会进入其中 这是我的缓存配置类: @Configuration @EnableCaching(proxyTargetClass = true) @PropertySource(CacheConfig.CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPER
CacheResolver
,因为我需要在运行时决定要使用哪个缓存,我没有任何编译错误,但是,当我做一些测试并在自定义的CacheResolver
上放置断点时,它永远不会进入其中
这是我的缓存配置类:
@Configuration
@EnableCaching(proxyTargetClass = true)
@PropertySource(CacheConfig.CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES)
public class CacheConfig extends CachingConfigurerSupport{
public static final String CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES = "classpath:/deploy/cache-properties.properties";
public static final String CACHEABLE_DOCUMENTS_PROPERTY = "cacheable.documents";
public static final String TTL_CACHEABLE_DOCUMENTS_PROPERTY = "ttl.cacheable.documents";
public static final String SIZED_CACHEABLE_DOCUMENTS_PROPERTY = "sized.cacheable.documents";
public static final String CACHE_NAME = "permanentCache";
public static final String TTL_CACHE = "ttlCache";
public static final String SIZED_CACHE = "sizedCache";
public static final String CACHEABLE_DOCUMENTS = "cacheableDocuments";
public static final String SIZED_CACHEABLE_DOCUMENTS = "sizedCacheableDocuments";
public static final int WEIGHT = 1000000;
public static final int TO_KBYTES = 1000;
@Inject
protected Environment environment;
//@Bean
@Override
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
GuavaCache sizedCache = new GuavaCache(SIZED_CACHE, CacheBuilder.newBuilder().maximumWeight(WEIGHT).weigher(
(key, storable) -> {
String json = ((Storable) storable).toJson();
return json.getBytes().length / TO_KBYTES;
}
).build());
GuavaCache permanentCache = new GuavaCache(CACHE_NAME,CacheBuilder.newBuilder().build());
//GuavaCache ttlCache = new GuavaCache(TTL_CACHE, CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build());
cacheManager.setCaches(Arrays.asList(permanentCache,sizedCache));
return cacheManager;
}
@Bean(name = "wgstCacheResolver")
@Override
public CacheResolver cacheResolver(){
CacheResolver cacheResolver = new WgstCacheResolver(cacheManager(),cacheableDocuments(),sizedCacheableDocuments());
return cacheResolver;
}
@Bean(name = CACHEABLE_DOCUMENTS)
public List<String> cacheableDocuments(){
String[] cacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(CACHEABLE_DOCUMENTS_PROPERTY));
return Arrays.asList(cacheableDocuments);
}
@Bean(name = SIZED_CACHEABLE_DOCUMENTS)
public List<String> sizedCacheableDocuments(){
String[] sizedCacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(SIZED_CACHEABLE_DOCUMENTS_PROPERTY));
return Arrays.asList(sizedCacheableDocuments);
}
}
@配置
@EnableCaching(proxyTargetClass=true)
@PropertySource(CacheConfig.CLASSPATH\u DEPLOY\u CACHE\u PROPERTIES\u PROPERTIES)
公共类CacheConfig扩展了CachingConfigurerSupport{
公共静态最终字符串CLASSPATH\u DEPLOY\u CACHE\u PROPERTIES\u PROPERTIES=“CLASSPATH:/DEPLOY/CACHE PROPERTIES.PROPERTIES”;
公共静态最终字符串CACHEABLE\u DOCUMENTS\u PROPERTY=“CACHEABLE.DOCUMENTS”;
公共静态最终字符串TTL\u CACHEABLE\u DOCUMENTS\u PROPERTY=“TTL.CACHEABLE.DOCUMENTS”;
公共静态最终字符串大小\u可缓存\u文档\u PROPERTY=“size.CACHEABLE.DOCUMENTS”;
公共静态最终字符串缓存\u NAME=“permanentCache”;
公共静态最终字符串TTL_CACHE=“ttlCache”;
公共静态最终字符串大小_CACHE=“sizedCache”;
公共静态最终字符串CACHEABLE_DOCUMENTS=“cacheableDocuments”;
公共静态最终字符串大小的可缓存文档=“SizedCachableDocuments”;
公共静态最终整数权重=1000000;
公共静态最终整数到千字节=1000;
@注入
保护环境;
//@豆子
@凌驾
公共缓存管理器缓存管理器(){
SimpleCacheManager cacheManager=新的SimpleCacheManager();
GuavaCache sizedCache=新的GuavaCache(SIZED_CACHE,CacheBuilder.newBuilder()。最大重量(重量)。称重器(
(键,可存储)->{
字符串json=((可存储)可存储).toJson();
将json.getBytes().length/返回到_KBYTES;
}
).build());
GuavaCache permanentCache=新的GuavaCache(CACHE_NAME,CacheBuilder.newBuilder().build());
//GuavaCache ttlCache=新的Guavache(TTL_缓存,CacheBuilder.newBuilder().expireAfterWrite(30,TimeUnit.MINUTES).build());
setCaches(Arrays.asList(permanentCache,sizedCache));
返回缓存管理器;
}
@Bean(name=“wgstcachesolver”)
@凌驾
公共CacheResolver CacheResolver(){
CacheSolver CacheSolver=新的WGSTCacheSolver(cacheManager(),cacheableDocuments(),sizedCacheableDocuments());
返回高速缓存解析器;
}
@Bean(名称=可缓存的文档)
公共列表可缓存文档(){
String[]cacheableDocuments=StringUtils.CommadeLimitedListToStringAray(environment.getProperty(CACHEABLE_DOCUMENTS_PROPERTY));
返回数组.asList(可缓存文档);
}
@Bean(名称=大小可缓存文档)
公共列表大小可缓存文档(){
String[]sizedCacheableDocuments=StringUtils.CommadeLimitedListToStringAray(environment.getProperty(SIZED\u CACHEABLE\u DOCUMENTS\u PROPERTY));
返回数组.asList(sizedCacheableDocuments);
}
}
这是我的缓存解析器
public class WgstCacheResolver extends AbstractCacheResolver {
private final List<String> cacheableDocuments;
private final List<String> sizedCacheableDocuments;
public WgstCacheResolver(final CacheManager cacheManager,final List<String> cacheableDocuments, final List<String> sizedCacheableDocuments) {
super(cacheManager);
this.cacheableDocuments = cacheableDocuments;
this.sizedCacheableDocuments = sizedCacheableDocuments;
}
/**
* Resolves the cache(s) to be updated on runtime
* @param context
* @return*/
@Override
protected Collection<String> getCacheNames(final CacheOperationInvocationContext<?> context) {
final Collection<String> cacheNames = new ArrayList<>();
final AbstractDao dao = (AbstractDao)context.getTarget();
final String documentType = dao.getDocumentType().toString();
if (cacheableDocuments.contains(documentType)){
cacheNames.add("permanentCache");
}
if (sizedCacheableDocuments.contains(documentType)){
cacheNames.add("sizedCache");
}
return cacheNames;
}
}
公共类wgstcachesolver扩展了AbstractCacheSolver{
私人最终清单文件;
私人最终列表大小可缓存文件;
公共WgstCacheResolver(最终缓存管理器缓存管理器、最终列表可缓存文档、最终列表大小可缓存文档){
高级(缓存管理器);
this.cacheableDocuments=cacheableDocuments;
this.sizedCachableDocuments=sizedCachableDocuments;
}
/**
*解析要在运行时更新的缓存
*@param上下文
*@返回*/
@凌驾
受保护的集合getCacheNames(最终缓存操作上下文){
最终集合cacheNames=new ArrayList();
final AbstractDao=(AbstractDao)context.getTarget();
最后一个字符串documentType=dao.getDocumentType().toString();
if(cacheableDocuments.contains(documentType)){
cacheNames.add(“permanentCache”);
}
if(sizedCacheableDocuments.contains(documentType)){
添加(“sizedCache”);
}
返回缓存名称;
}
}
这里是我使用缓存的DAO:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.DEFAULT)
@CacheConfig(cacheResolver = "wgstCacheResolver")
public class CacheableDao<T extends Storable> extends AbstractDao<T> {
private final Logger logger = LoggerFactory.getLogger(CacheableDao.class);
public CacheableDao(final Bucket bucket, final Class<T> typeParameterClass, final DocumentType documentType) {
super(bucket, typeParameterClass, documentType);
}
@Cacheable(key = "{#root.methodName, #root.target.generateFullKey(#key)}")
public T get(final String key) throws DatastoreAccessException, ObjectMappingException {
//do something
}
.
.
.
}
@组件
@范围(值=ConfigurableBeanFactory.Scope\u原型,proxyMode=ScopedProxyMode.DEFAULT)
@CacheConfig(cacheResolver=“wgstcachesolver”)
公共类CacheableDao扩展了AbstractDao{
私有最终记录器Logger=LoggerFactory.getLogger(CacheableDao.class);
公共CacheableDao(最终存储桶、最终类类型ParameterClass、最终文档类型DocumentType){
超级(bucket、typeParameterClass、documentType);
}
@可缓存(key=“{#root.methodName,#root.target.generativelkey(#key)}”)
公共T get(最终字符串键)抛出DatastoreAccessException、ObjectMappingException{
//做点什么
}
.
.
.
}
我尝试过实现CacheResolver
而不是扩展AbstractCacheResolver
,但没有任何区别
谢谢。缓存名称在某些时候需要包括在内,仅指定要使用的
缓存解析程序是不够的,@Cacheable
类需要知道可用的缓存名称,因此我将它们包括在@CacheConfig
注释中:
@CacheConfig(cacheNames = {WgstCacheConfig.PERMANENT_CACHE, WgstCacheConfig.SIZED_CACHE},
cacheResolver = WgstCacheConfig.WGST_CACHE_RESOLVER)
public class CacheableDao<T extends Storable> extends AbstractDao<T> {
所以我把它放在这里,它很有效:
@Bean
public CacheManager cacheManager() {
return null;
}
@Bean(name = WGST_CACHE_RESOLVER)
public CacheResolver cacheResolver(){
CacheResolver cacheResolver = new WgstCacheResolver(cacheableDocuments(),sizedCacheableDocuments(),getPermanentCache(),
getSizedCache());
return cacheResolver;
}
重新运行我的测试,单步执行我的自定义CacheResolver
,它将按照预期的方式解析到正确的缓存
我的配置类不再扩展CachingConfigurerSupport
。经过一番反复(很抱歉!)之后,发现这确实是Spring框架中的一个bug
我创造了。期待下一个维护版本(4.1.7.release
)的修复。感谢您的示例项目 您没有任何缓存名称,因此如果缓存有效,它必须解析缓存名称
@Bean
public CacheManager cacheManager() {
return null;
}
@Bean(name = WGST_CACHE_RESOLVER)
public CacheResolver cacheResolver(){
CacheResolver cacheResolver = new WgstCacheResolver(cacheableDocuments(),sizedCacheableDocuments(),getPermanentCache(),
getSizedCache());
return cacheResolver;
}