Spring 如何使用@EnableCache、多个缓存管理器和自定义缓存解析程序

Spring 如何使用@EnableCache、多个缓存管理器和自定义缓存解析程序,spring,spring-cache,Spring,Spring Cache,我正在尝试使用两个缓存管理器,一个默认,一个命名为(“new.kid”)。 命名的一个用于类NewKid中的特定方法,并由方法上的@Cacheable(cacheManager=“new.kid”)指定(无法为此问题更改注释设置) 我已经定义了一个自定义缓存解析程序,覆盖了getCacheNames,以便它为NewKid类型的目标返回new.kid缓存管理器缓存名称,否则返回defautl缓存名称 实际上,关于这方面的信息并不多,但从我收集的信息来看,如果有多个(默认的)CacheManager

我正在尝试使用两个缓存管理器,一个默认,一个命名为(“new.kid”)。 命名的一个用于类NewKid中的特定方法,并由方法上的@Cacheable(cacheManager=“new.kid”)指定(无法为此问题更改注释设置)

我已经定义了一个自定义缓存解析程序,覆盖了getCacheNames,以便它为NewKid类型的目标返回new.kid缓存管理器缓存名称,否则返回defautl缓存名称

实际上,关于这方面的信息并不多,但从我收集的信息来看,如果有多个(默认的)CacheManager,则必须使用自定义CacheResolver。 我已经定义了一个自定义缓存解析程序,覆盖了getCacheNames,以便它为NewKid类型的目标返回new.kid缓存管理器缓存名称,否则返回默认缓存管理器名称。 我的github中提供了完整的示例(从Spring缓存入门指南中复制和修改)


@组成部分
公共班新生{
@可缓存(cacheManager=“new.kid”)
公共字符串whatsYourName(字符串输入){
返回“新孩子名字”+输入;
}
}

@配置
公共类缓存管理器{
@Bean(“新的孩子”)
公共缓存管理器newKidCacheManager(){
CacheManager cmgr=新的CaffeineCacheManager();
((caffinecachemanager)cmgr.setCacheNames(Arrays.asList(cacheName));
((CaffeineCacheManager)cmgr.setCaffeine(Caffeine.newBuilder());
返回cmgr;
}
}

@配置
@启用缓存
公共类CacheManagerConfig扩展了CachingConfigurerSupport{
@自动连线
@限定符(value=“new.kid”)
CacheManager newKidCacheManager;
@豆子
@凌驾
公共缓存管理器缓存管理器(){
...
}
@豆子
@初级的
@凌驾
公共缓存解析程序缓存解析程序(){
返回新的CustomResolver(newKidCacheManager);
}

类CustomResolver扩展了AbstractCacheSolver{
公共CustomResolver(CacheManager newKidCacheManager){
this.newKidCacheManager=newKidCacheManager;
}
@凌驾
受保护的集合getCacheNames(CacheOperationInvocationContext CacheOperationInvocationContext){
if(新孩子的cacheOperationInvocationContext.getTarget()实例){
返回newKidCacheManager.getCacheNames();
}否则{
返回getCacheManager().getCacheNames();
}
}
}
如果我使用@EnableCaching注释,我就只能使用SimpleCacheSolver,它完全忽略了我的CustomResolver,尽管它是用@Primary@Bean注释的。 这会导致以下异常:


    No cache could be resolved for 'Builder[public java.lang.String hello.NewKid.whatsYourName(java.lang.String)] caches=[] | key='' | keyGenerator='' | cacheManager='new.kid' | cacheR
    esolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@171e2c13'. At least one cache should be provided per cache operation.

如果删除@EnableCaching,则会加载正确的CustomResolver,当然@Cacheable会被完全忽略,因此不会缓存方法结果

是我做错了什么,还是有人根本无法在自定义解析器中同时使用EnableCaching和多个CacheManager?这是怎么发生的?即使我有另一个标记为@Primary的CacheSolver bean,我也始终坚持使用SimpleCacheSolver?
如果有人能给我指出正确的方向,我会很高兴的

您必须指定要使用的自定义
CacheResolver
的bean名称,例如
@Cacheable(CacheResolver=“yourCustomResolverBeanName”)
不幸的是,我无法做到这一点。这个例子说明了我的现实问题,那就是我正在使用一个库,用@Cacheable(cacheManager=“…”)公开一个bean。我无法控制这一点,无论如何,我理解这应该是可行的。似乎在
@Cacheable(cacheManager)中缺少
value
属性=“new.kid”)
NewKid类中的注释。我认为您的案例中不需要自定义CacheResolver,因为您已经在注释中指定了
cacheManager
属性。来自
@Cacheable
docs cacheManager属性:“与{@link#CacheResolver}属性互斥“。因此,请尝试删除自定义缓存解析程序,并修复NewKid类中的注释,例如:
@Cacheable(value=“newdyName”,cacheManager=“new.kid”)
…还有一件事,将
CacheManager
bean中的一个标记为
@Primary
@tyonchev。你能解决这个问题吗?我也在寻找类似的解决方案。但在我的例子中,我有通用DAO类,在使用这个通用DAO时,为每个域对象查询寻找不同的缓存名称。你必须指定bean na请告诉我您想要使用的自定义
CacheResolver
,例如
@Cacheable(CacheResolver=“yourCustomResolverBeanName”)
,不幸的是,我无法做到这一点。这个示例说明了我的实际问题,即我正在使用一个库,使用@Cacheable(cacheManager=“…”)公开一个bean。我无法控制这一点,无论如何,我认为这应该有效。似乎您在
@Cacheable(cacheManager=“new.kid”)中缺少
属性
NewKid类中的注释。我认为您不需要自定义CacheResolver,因为您已经在注释中指定了
cacheManager
属性。来自
@Cacheable
docs cacheManager属性:“与{@link#CacheResolver}属性互斥”。因此,请尝试删除自定义缓存解析程序,并修复NewKid类中的注释,例如:
@Cacheable(value=“newkyname”,cacheManager=“new.kid”)
…还有一件事,将
CacheManager
bean中的一个标记为
@Primary
@tyonchev。你能解决这个问题吗?我也在寻找类似的解决方案。但在我的例子中,我有通用DAO类,在使用这个通用DAO时,为每个域对象查询寻找不同的缓存名称。