如何在弹簧缓存java中配置多个缓存管理器您有一个“主”缓存管理器更细粒度的分辨率
我希望在我的Web应用程序中配置多个spring缓存管理器,并且我可以在项目的不同位置使用不同的缓存管理器。有没有办法做到这一点。
我希望在我的Web应用程序中配置多个spring缓存管理器,并且我可以在项目的不同位置使用不同的缓存管理器。有没有办法做到这一点。
有几种方法可以做到这一点,正确的答案取决于您对缓存的使用情况。
如果您将 CacheManager A 用于 90% 的用例,将 B 用于 10%,我建议为 A 创建一个默认值(您需要通过扩展指定它),如下所示:CacheManager
CacheConfigurerSupport
@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() { ... }
}
请查看 的 javadoc 以获取更多详细信息。在实现中,您可能有几个实例(无论是否为 bean),您将根据逻辑在内部调用这些实例,以确定应使用哪个管理器。CacheResolver
CacheManager
我在评论中看到您指的是“模块”。缓存实际上是一个基础结构问题,因此我强烈建议您在应用程序级别上移动该决策。您可以将缓存标记为“本地”,而将其他缓存标记为“群集”。但是,您可能应该为名称使用某种命名法,以使其更容易。不要在模块级别选择缓存管理器。
这篇博客文章用其他例子说明了这一点。
正如@Stephane Nicoll所解释的那样,您有几种选择。我将尝试提供有关自定义的一些信息。 有一种方法:CacheResolver
CacheResolver
Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);
它为可缓存操作的类,方法,参数等提供上下文。
在其基本形式中:
public class CustomCacheResolver implements CacheResolver {
private final CacheManager cacheManager;
public CustomCacheResolver(CacheManager cacheManager){
this.cacheManager = cacheManager;
}
@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
Collection<Cache> caches = getCaches(cacheManager, context);
return caches;
}
private Collection<Cache> getCaches(CacheManager cacheManager, CacheOperationInvocationContext<?> context) {
return context.getOperation().getCacheNames().stream()
.map(cacheName -> cacheManager.getCache(cacheName))
.filter(cache -> cache != null)
.collect(Collectors.toList());
}
}
为了简洁起见,我在这里使用一个。但是您可以将不同的 绑定到 并进行更精细的选择:如果类名是 ,则使用 ,否则使用 。CacheManager
CacheManager
CacheResolver
X
GuavaCacheManager
EhCacheCacheManager
完成此步骤后,您应该注册 ,(同样,您可以在此处绑定更多内容):CacheResolver
CacheManagers
@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {
@Bean
@Override
public CacheManager cacheManager() {
// Desired CacheManager
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new CustomCacheResolver(cacheManager());
}
}
作为最后一步,您应该在其中一个 、 等注释中指定。CustomCacheResolver
@Cacheable
@CachePut
@CacheConfig
@Cacheable(cacheResolver="cacheResolver")
您可以在此处查找代码示例。