目前有两个不同的模块让项目A和项目B.项目B导入/使用到项目A中。目前项目B已经有了CacheManager。
项目B.
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
// using SimpleCacheManager()
}
}
但现在计划在项目A中实现缓存管理器以实现其他目的。
class SomeCacheConfig{
@Bean
public CacheManager someCacheManager(){
// using SimpleCacheManager()
}
}
加载应用程序时抛出异常。
java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary (or give it the name 'cacheManager') or declare a specific CacheManager to use, that serves as the default one.
你能帮我看看如何在多个模块/项目中实现多个cacheManager。
您可以使用Spring提供的CompositeCacheManager实现(https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/support/CompositeCacheManager.html)
这允许您撰写缓存管理器列表。复合管理器将遍历列表并在其存在的第一个管理器中获取缓存。请注意“注意:此复合管理器委托的常规CacheManagers需要从getCache(String)返回null,如果它们不知道指定的缓存名称,允许迭代到下一个委托。但是,大多数CacheManager实现都会在请求后回退到命名缓存的延迟创建;请查看具有固定缓存名称的“静态”模式的特定配置详细信息(如果可用)。
那好吧。将@Primary放在将用作默认值的CacheManager bean上。
@Primary
@Bean(name = "primaryCacheManager")
public CacheManager primaryCacheManager() {
return new SimpleCacheManager();
}
@Bean(name = "myCacheManager")
public CacheManager myCacheManager() {
return new SimpleCacheManager();
}
当你想使用另一个(即非默认值)时,使用@Qualifier注释显式定义CacheManager bean的名称。
@Autowired
@Qualifier("myCacheManager")
private CacheManager myCacheManager;
或者如果您使用annotation base Spring Cache implementation,您还可以将CacheManager名称定义为这些注释的属性
@Cacheable(value = "some",cacheManager = "myCacheManager")
public String getSome(){
return "";
}
Erik Ahlswede建议,最终对我有用
@Bean
public CacheManager cacheManager() {
return new CompositeCacheManager(
new ConcurrentMapCacheManager("cacheA") {
@Override
protected Cache createConcurrentMapCache(final String name) {
return new ConcurrentMapCache(name,
CacheBuilder.newBuilder()
.expireAfterWrite(CACHE_TTL_IN_SECONDS, TimeUnit.SECONDS)
.maximumSize(MAX_ENTRIES_IN_CACHE)
.build().asMap(), false);
}
},
new ConcurrentMapCacheManager("cacheB") {
@Override
protected Cache createConcurrentMapCache(final String name) {
return new ConcurrentMapCache(name,
CacheBuilder.newBuilder()
.expireAfterWrite(CACHE_TTL_IN_SECONDS, TimeUnit.SECONDS)
.maximumSize(MAX_ENTRIES_IN_CACHE)
.build().asMap(), false);
}
}
);
}
然后用它
@Cacheable("cacheA")
public String someComplicatedAction() {
}