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

使用Spring Data Redis时,访问对象如何重置其TTL?

Redis对象访问时自动重置TTL的实现方案

你当前的CodeTokenMap实体类通过@TimeToLive注解设置了TTL,但默认情况下Spring Data Redis不会在对象被访问时自动重置TTL。要实现"访问即刷新TTL"的需求,可以通过以下两种方案实现:

实体类回顾

@Data 
@RedisHash("CodeTokenMap") 
public class CodeTokenMap {
    @Id 
    String aCode;
    String acsToken;
    @TimeToLive private Long ttl;
}

方案一:自定义Repository方法(显式触发重置)

通过扩展Repository接口,添加专门的查询方法,在查询后手动重置TTL:

1. 定义Repository接口

public interface CodeTokenMapRepository extends CrudRepository<CodeTokenMap, String>, CodeTokenMapCustomRepository {
}

// 自定义扩展接口
interface CodeTokenMapCustomRepository {
    // 根据aCode查询并重置TTL
    CodeTokenMap findByACodeAndResetTtl(String aCode, Long newTtl);
}

2. 实现自定义Repository逻辑

@Repository
public class CodeTokenMapCustomRepositoryImpl implements CodeTokenMapCustomRepository {

    private final RedisTemplate<String, Object> redisTemplate;
    private static final String REDIS_KEY_PREFIX = "CodeTokenMap:";

    public CodeTokenMapCustomRepositoryImpl(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public CodeTokenMap findByACodeAndResetTtl(String aCode, Long newTtl) {
        String redisKey = REDIS_KEY_PREFIX + aCode;
        // 查询对象
        CodeTokenMap tokenMap = (CodeTokenMap) redisTemplate.opsForValue().get(redisKey);
        
        if (tokenMap != null) {
            // 重置Redis中该key的TTL
            redisTemplate.expire(redisKey, newTtl, TimeUnit.SECONDS);
            // 更新实体中的ttl字段并回写(可选,若需要保持实体与Redis中TTL一致)
            tokenMap.setTtl(newTtl);
            redisTemplate.opsForValue().set(redisKey, tokenMap, newTtl, TimeUnit.SECONDS);
        }
        return tokenMap;
    }
}

使用时直接调用findByACodeAndResetTtl("xxx", 30L)即可完成查询+TTL重置。

方案二:AOP切面(自动触发重置)

如果希望所有查询操作都自动重置TTL,无需显式调用特殊方法,可以用AOP切面拦截查询方法:

@Aspect
@Component
public class RedisTtlResetAspect {

    private final RedisTemplate<String, Object> redisTemplate;
    private static final String REDIS_KEY_PREFIX = "CodeTokenMap:";
    // 可通过@Value注入配置文件中的默认TTL
    private final Long defaultTtl = 30L;

    public RedisTtlResetAspect(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 拦截Repository中所有以find开头、参数为aCode的查询方法
    @AfterReturning(
        pointcut = "execution(* com.yourpackage.CodeTokenMapRepository.find*(..)) && args(aCode)",
        returning = "result"
    )
    public void resetTtlAfterQuery(String aCode, Object result) {
        if (result != null) {
            String redisKey = REDIS_KEY_PREFIX + aCode;
            // 重置TTL
            redisTemplate.expire(redisKey, defaultTtl, TimeUnit.SECONDS);
            
            // 可选:更新实体中的ttl字段
            if (result instanceof CodeTokenMap) {
                ((CodeTokenMap) result).setTtl(defaultTtl);
                redisTemplate.opsForValue().set(redisKey, result, defaultTtl, TimeUnit.SECONDS);
            }
        }
    }
}

注意事项

  • Redis key格式要与Spring Data Redis默认生成的一致:@RedisHash注解值:@Id字段值
  • 若使用动态TTL(实体中ttl字段为动态设置),可在重置时读取实体的ttl值而非固定值
  • 建议将TTL配置在application.properties中,通过@Value("${redis.ttl.code-token:30}")注入,避免硬编码

内容的提问来源于stack exchange,提问作者dead programmer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:15:33