我可以使用 ConcurrentMapCacheFactoryBean 自定义 Spring Boot simple ConcurrentMapCache 的存储吗?
Can I use ConcurrentMapCacheFactoryBean to customize the store of Spring Boot simple ConcurrentMapCache?
我正在使用带有一些 @Cacheable
和 @EnableCaching
注释的自动配置 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-caching-provider-simple。我有几个命名缓存。缓存按预期工作。
现在我想向我的缓存中添加 TTL 和其他一些自定义项。我尝试用 Guava 缓存替换 ConcurrentMapCacheManager 使用的默认 ConcurrentHashMap。我遵循了 的建议,并使用 ConcurrentMapCacheFactoryBean:
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanA() {
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("A");
cacheFactoryBean.setStore(CacheBuilder.newBuilder()
.expireAfterWrite(DURATION, TimeUnit.SECONDS)
.build()
.asMap());
return cacheFactoryBean;
}
我的缓存名称是 A、B 或 C
@Cacheable("A")
由于我需要3个缓存,看来我需要配置3个不同缓存名称的ConcurrentMapCacheFactoryBeans?
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanA() {
cacheFactoryBean.setName("A");
...
}
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanB() {
cacheFactoryBean.setName("B");
...
}
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanC() {
cacheFactoryBean.setName("C");
...
}
这是正确的做法吗?有没有更简单的方法来配置 ConcurrentMapCache 存储?这样我就失去了我之前的自动缓存创建,我可以在某些方法中添加注释 @Cacheable("D")
,并且缓存 D 会自动创建。
我知道 Spring Boot 已将 Guava 缓存支持替换为自动配置的 Caffeine 支持,它具有 TTL 属性,我也可以切换到该轨道。但我喜欢这种方法的灵活性,也很好奇。
我最终忘记了 ConcurrentMapCacheFactoryBean
并自定义 CacheManager
而不是覆盖 ConcurrentMapCacheManager
的 createConcurrentMapCache(name)
。这很简单:
@Configuration
public class TtlConcurrentMapCacheConfiguration {
public static final int TTL_SECONDS = 60;
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager() {
@Override
protected Cache createConcurrentMapCache(String name) {
// storeByValue is false by default (for ConcurrentMapCaches) and wont be true unless we set it
// explicitly. I think it is enough to just not support storeByValue, and keep things simple.
// https://github.com/spring-projects/spring-framework/issues/18331
if (isStoreByValue()) {
throw new IllegalStateException("storeByValue is not supported");
}
ConcurrentMap<Object, Object> store = CacheBuilder.newBuilder()
.expireAfterWrite(TTL_SECONDS, TimeUnit.SECONDS)
.build()
.asMap();
return new ConcurrentMapCache(name, store, isAllowNullValues());
}
};
}
}
我不知道我在哪里找到了 ConcurrentMapCacheFactoryBean,也不知道为什么有三个,一个用于我的缓存,就像他们在我的问题中所做的那样。可能我的一些搜索发现了一些信息,使我误入歧途。
我正在使用带有一些 @Cacheable
和 @EnableCaching
注释的自动配置 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-caching-provider-simple。我有几个命名缓存。缓存按预期工作。
现在我想向我的缓存中添加 TTL 和其他一些自定义项。我尝试用 Guava 缓存替换 ConcurrentMapCacheManager 使用的默认 ConcurrentHashMap。我遵循了 的建议,并使用 ConcurrentMapCacheFactoryBean:
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanA() {
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("A");
cacheFactoryBean.setStore(CacheBuilder.newBuilder()
.expireAfterWrite(DURATION, TimeUnit.SECONDS)
.build()
.asMap());
return cacheFactoryBean;
}
我的缓存名称是 A、B 或 C
@Cacheable("A")
由于我需要3个缓存,看来我需要配置3个不同缓存名称的ConcurrentMapCacheFactoryBeans?
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanA() {
cacheFactoryBean.setName("A");
...
}
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanB() {
cacheFactoryBean.setName("B");
...
}
@Bean
public ConcurrentMapCacheFactoryBean cacheFactoryBeanC() {
cacheFactoryBean.setName("C");
...
}
这是正确的做法吗?有没有更简单的方法来配置 ConcurrentMapCache 存储?这样我就失去了我之前的自动缓存创建,我可以在某些方法中添加注释 @Cacheable("D")
,并且缓存 D 会自动创建。
我知道 Spring Boot 已将 Guava 缓存支持替换为自动配置的 Caffeine 支持,它具有 TTL 属性,我也可以切换到该轨道。但我喜欢这种方法的灵活性,也很好奇。
我最终忘记了 ConcurrentMapCacheFactoryBean
并自定义 CacheManager
而不是覆盖 ConcurrentMapCacheManager
的 createConcurrentMapCache(name)
。这很简单:
@Configuration
public class TtlConcurrentMapCacheConfiguration {
public static final int TTL_SECONDS = 60;
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager() {
@Override
protected Cache createConcurrentMapCache(String name) {
// storeByValue is false by default (for ConcurrentMapCaches) and wont be true unless we set it
// explicitly. I think it is enough to just not support storeByValue, and keep things simple.
// https://github.com/spring-projects/spring-framework/issues/18331
if (isStoreByValue()) {
throw new IllegalStateException("storeByValue is not supported");
}
ConcurrentMap<Object, Object> store = CacheBuilder.newBuilder()
.expireAfterWrite(TTL_SECONDS, TimeUnit.SECONDS)
.build()
.asMap();
return new ConcurrentMapCache(name, store, isAllowNullValues());
}
};
}
}
我不知道我在哪里找到了 ConcurrentMapCacheFactoryBean,也不知道为什么有三个,一个用于我的缓存,就像他们在我的问题中所做的那样。可能我的一些搜索发现了一些信息,使我误入歧途。