概述
在这个简短教程中,我们将探讨如何在Spring Data Redis中配置键过期时间。
2. 设置
首先,我们创建一个基于Spring Boot的API,用于管理由Redis持久化的会话资源。要做到这一点,我们需要四个主要步骤。有关更详细的设置,请参阅我们的指南:Spring Data Redis教程。
2.1. 依赖项
首先,在pom.xml
中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.0.4</version>
</dependency>
spring-boot-starter-data-redis
将隐式添加spring-data-redis
和lettuce-core
。
2.2. Redis配置
其次,让我们添加RedisTemplate
配置:
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
2.3. 模型
第三步,创建我们的会话模型:
@RedisHash
public class Session {
@Id
private String id;
private Long expirationInSeconds;
}
2.4. Redis仓库
最后,创建SessionRepository
,它提供与Redis的交互,以管理我们的Session
实体:
public interface SessionRepository extends CrudRepository<Session, String> {}
3. 方法
我们将探讨三种设置TTL的方法。
3.1. 使用@RedisHash
我们从最简单的方法开始。@RedisHash
允许我们为其timeToLive
属性提供一个值:
@RedisHash(timeToLive = 60L)
public class Session {
@Id
private String id;
private Long expirationInSeconds;
}
它以秒为单位接受值。 在上面的例子中,我们将过期时间设置为60秒。这种方法适用于当我们希望为所有Session
对象提供恒定的TTL值时。也可以指定默认TTL。
3.2. 使用@TimeToLive
在前一种方法中,我们可以为所有Session
对象设置相同的恒定TTL。接下来的方法更具动态性。使用@TimeToLive
,我们可以注解任何数值属性或返回数值值的方法来设置TTL:
@RedisHash(timeToLive = 60L)
public class Session {
@Id
private String id;
@TimeToLive
private Long expirationInSeconds;
}
这允许我们为每个Session
对象动态设置TTL。与前一种方法一样,TTL也是以秒为单位。@TimeToLive
的值优先于@RedisHash(timeToLive)
。
3.3. 使用KeyspaceSettings
接下来的方法是使用KeyspaceSettings
设置TTL。键空间定义了实际用于Redis哈希键创建的前缀。现在,让我们为Session
类定义KeyspaceSettings
:
@Configuration
@EnableRedisRepositories(keyspaceConfiguration = RedisConfiguration.MyKeyspaceConfiguration.class)
public class RedisConfiguration {
// Other configurations omitted
public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {
@Override
protected Iterable<KeyspaceSettings> initialConfiguration() {
KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
keyspaceSettings.setTimeToLive(60L);
return Collections.singleton(keyspaceSettings);
}
}
}
就像前面的方法一样,我们也在秒为单位指定了TTL。这种方法与@RedisHash
类似。此外,如果我们不希望使用@EnableRepositories
,可以更程序化地设置它:
@Configuration
public class RedisConfiguration {
// Other configurations omitted
@Bean
public RedisMappingContext keyValueMappingContext() {
return new RedisMappingContext(new MappingConfiguration(new IndexConfiguration(), new MyKeyspaceConfiguration()));
}
public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {
@Override
protected Iterable<KeyspaceSettings> initialConfiguration() {
KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
keyspaceSettings.setTimeToLive(60L);
return Collections.singleton(keyspaceSettings);
}
}
}
4. 比较
最后,让我们比较我们研究的三种方法,并确定何时使用它们。
@RedisHash
和KeyspaceSettings
都允许我们为所有实体实例(例如Session
)设置TTL一次。而@TimeToLive
则允许我们为每个实体实例动态设置TTL。
KeyspaceSettings
提供了一种在一个位置为多个实体设置默认TTL的方法。相比之下,@TimeToLive
和@RedisHash
需要在每个实体类文件中进行设置。
@TimeToLive
具有最高的优先级,其次是@RedisHash
,最后是KeyspaceSettings
。
5. Redis键过期事件
使用这些设置Redis键过期时间的方法后,我们可能还对何时发生此类事件感兴趣。为此,我们有RedisKeyExpiredEvent
。让我们设置一个EventListener
来捕获RedisKeyExpiredEvent
:
@Configuration
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
@Slf4j
public class RedisConfiguration {
// Other configurations omitted
@Component
public static class SessionExpiredEventListener {
@EventListener
public void handleRedisKeyExpiredEvent(RedisKeyExpiredEvent<Session> event) {
Session expiredSession = (Session) event.getValue();
assert expiredSession != null;
log.info("Session with key={} has expired", expiredSession.getId());
}
}
}
现在,我们将能够知道何时会话过期,并在需要时采取行动:
2023-02-10T15:13:38.626+05:30 INFO 16874 --- [enerContainer-1] c.b.s.config.RedisConfiguration:
Session with key=edbd98e9-7b50-45d8-9cf4-9c621899e213 has expired
6. 结论
在这篇文章中,我们探讨了通过Spring Data Redis设置Redis TTL的各种方法。最后,我们讨论了RedisKeyExpiredEvent
以及如何处理过期事件。
如往常一样,代码可在GitHub上找到。