You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ReactiveRedisTemplate能否为缓存键设置默认TTL?

ReactiveRedisTemplate 为不同缓存键预设默认TTL的实现方案

当然可以实现,下面提供几种适配ReactiveRedisTemplate的方案,满足不同缓存键预设不同TTL的需求:

方式一:封装自定义缓存服务层(最直接易维护)

  • 先维护一个键与TTL的映射配置,明确每个键的过期时间:
private static final Map<String, Long> KEY_TTL_MAP = Map.of(
    "key1", 100L,  // key1 过期时间100秒
    "key2", 200L   // key2 过期时间200秒
);
  • 基于ReactiveRedisTemplate封装通用存值方法,自动匹配对应TTL:
@Service
public class ReactiveCacheService {
    private final ReactiveRedisTemplate<String, Object> reactiveRedisTemplate;

    // 构造注入ReactiveRedisTemplate
    public ReactiveCacheService(ReactiveRedisTemplate<String, Object> reactiveRedisTemplate) {
        this.reactiveRedisTemplate = reactiveRedisTemplate;
    }

    // 自动应用预设TTL的存值方法
    public Mono<Boolean> putWithDefaultTtl(String key, Object value) {
        // 找不到对应键的话用默认TTL,这里设为300秒
        Long ttl = KEY_TTL_MAP.getOrDefault(key, 300L);
        return reactiveRedisTemplate.opsForValue().set(key, value, Duration.ofSeconds(ttl));
    }

    // 可按需扩展其他操作,比如putIfAbsentWithDefaultTtl等
}
  • 使用时直接调用该服务的方法,无需每次手动指定TTL,自动遵循预设规则。

方式二:扩展ReactiveRedisTemplate(更灵活的底层封装)

  • 自定义带TTL配置的ReactiveRedisTemplate子类,内置键-TTL映射:
public class TtlAwareReactiveRedisTemplate<K, V> extends ReactiveRedisTemplate<K, V> {
    private final Map<K, Long> keyTtlMap;
    private final Long defaultTtl;

    public TtlAwareReactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory, 
                                         RedisSerializer<K> keySerializer, 
                                         RedisSerializer<V> valueSerializer,
                                         Map<K, Long> keyTtlMap, 
                                         Long defaultTtl) {
        super(connectionFactory, keySerializer, valueSerializer);
        this.keyTtlMap = keyTtlMap;
        this.defaultTtl = defaultTtl;
    }

    @Override
    public ReactiveValueOperations<K, V> opsForValue() {
        return new TtlAwareReactiveValueOperations<>(super.opsForValue(), keyTtlMap, defaultTtl);
    }

    // 自定义ValueOperations实现,重写set方法自动应用TTL
    private static class TtlAwareReactiveValueOperations<K, V> implements ReactiveValueOperations<K, V> {
        private final ReactiveValueOperations<K, V> delegate;
        private final Map<K, Long> keyTtlMap;
        private final Long defaultTtl;

        public TtlAwareReactiveValueOperations(ReactiveValueOperations<K, V> delegate, 
                                               Map<K, Long> keyTtlMap, 
                                               Long defaultTtl) {
            this.delegate = delegate;
            this.keyTtlMap = keyTtlMap;
            this.defaultTtl = defaultTtl;
        }

        // 重写无timeout参数的set方法,自动应用预设TTL
        @Override
        public Mono<Boolean> set(K key, V value) {
            Long ttl = keyTtlMap.getOrDefault(key, defaultTtl);
            return delegate.set(key, value, Duration.ofSeconds(ttl));
        }

        // 其他方法直接委托给原实现,保留手动指定TTL的能力
        @Override
        public Mono<Boolean> set(K key, V value, Duration timeout) {
            return delegate.set(key, value, timeout);
        }

        // 省略其他接口方法的委托实现(可直接调用delegate对应方法)
    }
}
  • 在配置类中注册自定义模板:
@Configuration
public class RedisConfig {
    @Bean
    public TtlAwareReactiveRedisTemplate<String, Object> ttlAwareReactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) {
        Map<String, Long> keyTtlMap = Map.of(
            "key1", 100L,
            "key2", 200L
        );
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer<Object> valueSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 默认TTL设为300秒
        return new TtlAwareReactiveRedisTemplate<>(connectionFactory, keySerializer, valueSerializer, keyTtlMap, 300L);
    }
}
  • 使用时注入TtlAwareReactiveRedisTemplate,调用opsForValue().set(key, value)即可自动应用预设TTL。

补充:结合Spring Cache注解的场景

如果你的项目用Spring Cache注解(如@Cacheable),可以搭配ReactiveRedisCacheManager配置,逻辑和你熟悉的RedisCacheManager一致,只是用响应式版本:

@Bean
public ReactiveRedisCacheManager reactiveRedisCacheManager(ReactiveRedisConnectionFactory connectionFactory) {
    // 默认缓存配置,TTL 300秒
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofSeconds(300));

    // 不同缓存名称对应不同TTL
    Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
    cacheConfigs.put("key1Cache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(100)));
    cacheConfigs.put("key2Cache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(200)));

    return ReactiveRedisCacheManager.builder(connectionFactory)
            .cacheDefaults(defaultConfig)
            .withInitialCacheConfigurations(cacheConfigs)
            .build();
}

使用时通过@Cacheable(cacheNames = "key1Cache")指定缓存名称,就能自动应用对应TTL。

内容的提问来源于stack exchange,提问作者Andre Hrs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:52:46