java 在 Spring Cache 中使用多个缓存实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41985344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:17:11  来源:igfitidea点击:

Using multiple cache implementations with Spring Cache

javaspringcachingspring-bootspring-cache

提问by Balazs

I'm working on a Spring Bootapp where I need to use both distributed (e.g. Hazelcast) and local (e.g. Guava) caches. Is there a way to configure Spring Cache to use both when using @Cacheableand decide which implementation is needed based on the cache name?

我正在开发一个Spring Boot应用程序,我需要同时使用分布式(例如Hazelcast)和本地(例如Guava)缓存。有没有办法将 Spring Cache 配置为在使用时使用@Cacheable并根据缓存名称决定需要哪种实现?

I tried with creating a configuration for both HZ and Guava defining the cache names inside, but Spring complains that it couldn't find the cache name that is supposed to handled by HZ. When I use exclusively HZ or Guava they work.

我尝试为 HZ 和 Guava 创建一个配置,在里面定义缓存名称,但 Spring 抱怨它找不到应该由 HZ 处理的缓存名称。当我只使用 HZ 或 Guava 时,它们会起作用。

回答by Arpit Aggarwal

Which implementation is needed based on the cache name?

根据缓存名称需要哪种实现?

Not based on the cache name but yes based on CacheManagerits possible, declare one of them as Primary CacheManager, as follows:

不是基于缓存名称而是基于CacheManager是可能的,将其中之一声明为Primary CacheManager,如下所示:

@Configuration
@EnableCaching
@PropertySource(value = { "classpath:/cache.properties" })
public class CacheConfig {

    @Bean
    @Primary
    public CacheManager hazelcastCacheManager() {
        ClientConfig config = new ClientConfig();
        HazelcastInstance client = HazelcastClient.newHazelcastClient(config);
        return new HazelcastCacheManager(client);
    }

    @Bean
    public CacheManager guavaCacheManager() {
         GuavaCacheManager cacheManager = new GuavaCacheManager("mycache");
           CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()
           .maximumSize(100)
           .expireAfterWrite(10, TimeUnit.MINUTES);
           cacheManager.setCacheBuilder(cacheBuilder);
           return cacheManager;
    }

}

And specify it at class level as:

并将其在类级别指定为:

@Service
@CacheConfig(cacheManager="hazelcastCacheManager")
public class EmployeeServiceImpl implements IEmployeeService {

}

Or at method level as:

或在方法级别为:

@Service
public class EmployeeServiceImpl implements IEmployeeService {

    @Override
    @Cacheable(value = "EMPLOYEE_", key = "#id", cacheManager= "guavaCacheManager")
    public Employee getEmployee(int id) {
        return new Employee(id, "A");
    }

}

If you have to stick on Cache name only then you can multiple CacheManager.

如果您只需要坚持缓存名称,那么您可以使用多个 CacheManager。

回答by isaolmez

You have 2 options.

您有 2 个选择。

One is as @Arpit mentioned: Define multiple CacheManagers and specify it in either method-level annotations (@Cacheable, @CachePut, etc) or class-level annotations (@CacheConfig)

一个是@Arpit 提到的:定义多个 CacheManager 并在方法级注释(@Cacheable、@CachePut 等)或类级注释(@CacheConfig)中指定它

You can also create custom annotations:

您还可以创建自定义注释:

@CacheConfig(cacheManager = "guavaCacheManager")
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface GuavaCacheable {
}

@GuavaCacheable
@Service
public class MyServiceImpl implements MyService {
}

And as the second option, you can create a custom cache resolver if your caching needs are complex.

作为第二个选项,如果您的缓存需求很复杂,您可以创建自定义缓存解析器。

You can look herefor a custom CacheResolver that manages multiple CacheManagers and supports enabling/disabling. But for most cases, CacheResolver is overkill.

您可以在此处查找管理多个 CacheManager 并支持启用/禁用的自定义 CacheResolver。但在大多数情况下,CacheResolver 是矫枉过正的。