Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SpringCacheJava中配置多个缓存管理器_Java_Spring_Caching_Spring Boot_Spring Cache - Fatal编程技术网

如何在SpringCacheJava中配置多个缓存管理器

如何在SpringCacheJava中配置多个缓存管理器,java,spring,caching,spring-boot,spring-cache,Java,Spring,Caching,Spring Boot,Spring Cache,我希望在我的web应用程序中配置多个spring缓存管理器,并且我能够在项目的不同位置使用不同的缓存管理器。有什么方法可以做到这一点。有几种方法可以做到这一点,正确的答案取决于您对缓存的使用情况 您有一个“主”缓存管理器 如果90%的用例使用CacheManager A,10%使用CacheManager B,我建议为A创建一个默认的CacheManager(您需要通过CacheConfigureSupport扩展指定),类似于: @Configuration @EnableCaching pu

我希望在我的web应用程序中配置多个spring缓存管理器,并且我能够在项目的不同位置使用不同的缓存管理器。有什么方法可以做到这一点。

有几种方法可以做到这一点,正确的答案取决于您对缓存的使用情况

您有一个“主”缓存管理器 如果90%的用例使用CacheManager A,10%使用CacheManager B,我建议为A创建一个默认的
CacheManager
(您需要通过
CacheConfigureSupport
扩展指定),类似于:

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Override
    @Bean // not strictly necessary
    public CacheManager cacheManager() { ... CacheManager A }

    @Bean
    public CacheManager bCacheManager() { ... CacheManager B }
}
然后,对于10%的用例,在需要使用其他缓存管理器的类的顶部添加一个
CacheConfig

@CacheConfig(cacheManager="bCacheManager")
public class MyService { /*...*/ }
如果只需要对一个方法使用另一个缓存管理器,也可以在方法级别指定该方法

@Cacheable(cacheNames = "books", cacheManager = "bCacheManager")
public Book findById(long id) { /*...*/ }
更细粒度的分辨率 如果您不在这种情况下,您需要一种方法来了解需要根据具体情况使用哪个缓存管理器。您可以根据目标类型(
MyService
)或缓存名称(
books
)来执行此操作。您需要实现一个
CacheResolver
,为您进行转换

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Override
    public CacheResolver cacheResolver() { ... }
}
有关更多详细信息,请查看
CacheResolver
的javadoc。在实现中,您可能有几个
CacheManager
实例(作为bean或不作为bean),您将根据逻辑在内部调用这些实例,以确定应该使用哪个管理器

我在评论中看到你指的是“模块”。缓存实际上是一个基础设施问题,因此我强烈建议您在应用程序级别做出决定。您可以将缓存标记为“本地”,而将其他缓存标记为“集群”。但是你可能应该对这个名字有一些命名法,让它更简单。不要在模块级别选择缓存管理器


用其他例子说明了这一点。

正如@Stephane Nicoll所解释的,您有几个选择。 我将尝试提供有关自定义
CacheResolver
的一些信息
CacheResolver
有一种方法:

Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);
作为最后一步,您应该在
@Cacheable
@CachePut
@CacheConfig
等注释之一中指定
CustomCacheResolver

@Cacheable(cacheResolver="cacheResolver")

您可以查找代码示例。

您可以像这样编写customer CacheManager bean

    @Primary
    @Bean("customerCacheManager")
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        Map<String, Long> expires = new HashMap<>();
        expires.put("fundShareSplit", TimeUnit.SECONDS.toSeconds(60));
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        cacheManager.setExpires(expires);
        List<String> cacheNames = Arrays.asList("fundShareSplit");
        cacheManager.setCacheNames(cacheNames);
        return cacheManager;
    }
 @Cacheable(cacheManager = "customerCacheManager",value = "fundShareSplit",key="'smile:asset:fundSplit:fundId:'+#root.args[0]+'_localDate:'+#root.args[1]",unless="#result == null")

到目前为止,您发现了什么?我已经在我的项目的一个模块中配置了EHCacheManager,现在我想在另一个模块中使用RedisCacheManager,但是spring不允许在单个应用程序上下文中有2个CacheManager类型的bean。然后我在配置类中实现了cachingconfiguer以避免这个问题。但我的ApplicationContext中只有EHCacheManager类型的CacheManager bean。但我的要求是创建两个cacheManagers bean,并且我应该能够在不同的模块中使用这两个。我听说过CompositeCacheManager,不确定这是否有帮助。感谢alotStephane,我正在采用这种方法来扩展Spring引导默认配置,但这似乎是解决我问题的一种原始方法,您能给我建议一种更好的解决方法吗?thankswatch out:在spring boot 1.5中,当扩展CachingConfigurerSupport时,您正在重写一些方法(默认的keyGenerator和errorHandler),这会使缓存变得无用。我使用了相同的方法,但没有扩展该类。仅仅声明bean就足以让它工作。你不必重写那些方法。如果您不这样做,将使用默认的
KeyGenerator
ErrorHandler
。您好,谢谢您的回答。除了Spring创建的默认cacheManager之外,是否还可以创建cacheManager?实际上,我让Spring自动配置JCacheManager,使用ehcache,我将保留默认配置,而不必重新定义它。当我创建自己的cacheManager时,由于@ConditionalOnMissingBean,默认的cacheManager不会再创建。请不要在评论中提问。答案是否定的,如果您创建自己的,自动配置将按其应该的方式退出。也就是说,您不必将其创建为bean。
    @Primary
    @Bean("customerCacheManager")
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        Map<String, Long> expires = new HashMap<>();
        expires.put("fundShareSplit", TimeUnit.SECONDS.toSeconds(60));
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        cacheManager.setExpires(expires);
        List<String> cacheNames = Arrays.asList("fundShareSplit");
        cacheManager.setCacheNames(cacheNames);
        return cacheManager;
    }
 @Cacheable(cacheManager = "customerCacheManager",value = "fundShareSplit",key="'smile:asset:fundSplit:fundId:'+#root.args[0]+'_localDate:'+#root.args[1]",unless="#result == null")