如何在多个模块/项目中使用多个缓存管理器配置spring cache java

时间:2018-02-13 15:10:13

标签: java spring-boot caching guava

目前有两个不同的模块让我们说项目A和项目B.项目B导入/使用到项目A中。目前项目B已经有了CacheManager。

项目B

  public class CacheConfig {

  @Bean 
  public CacheManager cacheManager() {

  // using SimpleCacheManager()

  }
 }

但是现在计划在项目A中实现CacheManager以实现其他目的。

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。

3 个答案:

答案 0 :(得分:1)

您可以使用Spring(https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/support/CompositeCacheManager.html)提供的CompositeCacheManager实现

这使您可以组成一个缓存管理器列表。组合管理器将遍历该列表,并在其所在的第一个管理器中获取缓存。请注意:“注意:如果该复合管理器不知道指定的常规CacheManager,则它们需要从getCache(String)返回null。缓存名称,允许迭代到下一个委托中。但是,大多数CacheManager实现都会回退到延迟创建命名缓存的情况;请查看带有固定缓存名称的“静态”模式的特定配置详细信息(如果有)。”

答案 1 :(得分:0)

那好吧。 将@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 "";
}

答案 2 :(得分:0)

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() {

}