使用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
相关产品推荐
相关产品推荐

