我可以使用 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 而不是覆盖 ConcurrentMapCacheManagercreateConcurrentMapCache(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,也不知道为什么有三个,一个用于我的缓存,就像他们在我的问题中所做的那样。可能我的一些搜索发现了一些信息,使我误入歧途。