如何在 Springboot2.0 中使用 @cacheable 时为每个 Redis 缓存配置不同的 TTL



我在 springboot2.0 中使用 @cacheable 和 redis 一起。我已经配置了RedisCacheManager如下:

@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
SerializationPair<Object> valueSerializationPair = RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer());
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
cacheConfiguration = cacheConfiguration.serializeValuesWith(valueSerializationPair);
cacheConfiguration = cacheConfiguration.prefixKeysWith("myPrefix");
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(30));
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
return redisCacheManager;
}

但是这使得所有键的TTL为30秒,如何为每个具有不同缓存名称的Redis缓存配置不同的TTL?

您可以仅使用一个 CacheManager 为每个缓存配置不同的过期时间,方法是为每个缓存创建不同的配置,并将它们放在用于创建 CacheManager 的映射中。

例如:

@Bean
RedisCacheWriter redisCacheWriter() {
return RedisCacheWriter.lockingRedisCacheWriter(jedisConnectionFactory());
}
@Bean
RedisCacheConfiguration defaultRedisCacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(defaultCacheExpiration));
}
@Bean
CacheManager cacheManager() {
Map<String, RedisCacheConfiguration> cacheNamesConfigurationMap = new HashMap<>();
cacheNamesConfigurationMap.put("cacheName1", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl1)));
cacheNamesConfigurationMap.put("cacheName2", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl2)));
cacheNamesConfigurationMap.put("cacheName3", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl3)));
return new RedisCacheManager(redisCacheWriter(), defaultRedisCacheConfiguration(), cacheNamesConfigurationMap);
}

如果需要在使用@cacheable时为缓存配置不同的过期时间, 您可以使用不同的 ttl 配置不同的缓存管理器,并在服务中使用缓存时指定缓存管理器。

@Cacheable(cacheManager = "expireOneHour", value = "onehour", key = "'_onehour_'+#key", sync = true)

以下是使用 Redisson Java 客户端定义多个具有不同TTLmaxIdleTime的基于 Redis 的缓存的方法:

@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:7004", "redis://127.0.0.1:7001");
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
// create "myCache1" cache with ttl = 20 minutes and maxIdleTime = 12 minutes
config.put("myCache", new CacheConfig(24*60*1000, 12*60*1000));
// create "myCache2" cache with ttl = 35 minutes and maxIdleTime = 24 minutes
config.put("myCache2", new CacheConfig(35*60*1000, 24*60*1000));
return new RedissonSpringCacheManager(redissonClient, config);
}

这是我的代码:

  1. 通用模块中的共享配置

    @Bean
    RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(List<RedisTtlConfig> ttlConfigs) {
    RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
    return (builder) -> {
    Map<String, RedisCacheConfiguration> ttlConfigMap = new HashMap<>();
    ttlConfigs.forEach( config -> {
    config.forEach( (key, ttl) -> {
    ttlConfigMap.put(key, defaultCacheConfig.entryTtl(Duration.ofSeconds(ttl)));
    });
    });
    builder.withInitialCacheConfigurations(ttlConfigMap);
    builder.cacheDefaults(defaultCacheConfig);
    };
    }
    
  2. 用于按键收集 ttl 配置的自定义类

    public class RedisTtlConfig extends HashMap<String, Long> {
    public RedisTtlConfig setTTL(String key, Long ttl){
    this.put(key, ttl);
    return this;
    }
    }
    

3.引用模块中的简单ttl配置代码

@Bean
RedisTtlConfig corpCacheTtlConfig(){
return new RedisTtlConfig()
.setTTL("test1", 300l)
.setTTL("test2", 300l);
}

最新更新