除了配置文件yml里的内容,我们还需要Redis配置和封装:
package com.llpp.config;
import io.lettuce.core.resource.DefaultClientResources;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@EnableCaching // 开启缓存
@Configuration // 配置类
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host:localhost}")
private String redisHost;
@Value("${spring.redis.port:6379}")
private int redisPort;
@Value("${spring.redis.password:}")
private String redisPassword;
/**
* 配置 Redis 连接工厂并启用连接池
* 意义: LettuceConnectionFactory 是连接 Redis 服务器的入口,它使用了 Lettuce 客户端,并启用了连接池以提高性能。
*
* @return LettuceConnectionFactory
*/
@Bean
public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
// 配置 Redis 服务器的连接信息
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisHost);
redisStandaloneConfiguration.setPort(redisPort);
if (!redisPassword.isEmpty()) {
redisStandaloneConfiguration.setPassword(redisPassword);
}
// 启用 Lettuce 连接池
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.clientResources(DefaultClientResources.create())
.commandTimeout(redisProperties.getTimeout())
.shutdownTimeout(redisProperties.getLettuce().getShutdownTimeout())
.build();
// 创建使用连接池的 Lettuce 连接工厂
return new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
}
/**
* 配置并返回一个 RedisTemplate 实例,用于执行 Redis 操作
* 意义: RedisTemplate 提供了一种高级抽象,使得开发者可以通过模板方法操作 Redis,而无需直接处理底层的 Redis 命令。
* 它支持多种 Redis 操作,例如值操作、哈希操作、列表操作等
*
* @return RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
/*
1.创建 RedisTemplate: 这是 Spring 用于与 Redis 交互的核心类,简化了与 Redis 的交互。
2.设置连接工厂: 使用前面定义的 LettuceConnectionFactory。
3.设置序列化器: 设置键和值的序列化器,这里使用 StringRedisSerializer 来将键和值序列化为字符串。
*/
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory); // 设置连接工厂
template.setKeySerializer(new StringRedisSerializer()); // 设置键的序列化器
template.setValueSerializer(new StringRedisSerializer()); // 设置值的序列化器
return template;
}
}
package com.llpp.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/**
* RedisService 类提供了简化的 Redis 操作接口,用于在 Spring Boot 应用中存储和检索数据。
* 它通过 RedisTemplate 与 Redis 服务器交互,执行常见的操作如设置值、获取值、设置值带过期时间和删除值。
* 此外,该类还支持使用 Duration 对象来设置键值对的过期时间。
*/
@Service
@RequiredArgsConstructor
public class RedisService {
// RedisTemplate 是 Spring 提供的一个 Redis 操作模板,它抽象了 Redis 的底层访问,
// 使开发者可以用 Java 对象操作 Redis。使用 @Autowired 注解,Spring 自动将配置好的 RedisTemplate 注入到 RedisService 类中
private final RedisTemplate<String, Object> redisTemplate;
/**
* 向 Redis 中存储一个键值对。
*
* @param key 存储的键
* @param value 存储的值
*/
public void setValue(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 从 Redis 中获取指定键的值。
*
* @param key 要获取的键
* @return 对应键的值,如果不存在则返回 null
*/
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 从 Redis 中获取指定键的值。
*
* @param key 要获取的键
* @return 对应键的值,如果不存在则返回 默认值
*/
public Object getValueOrDefault(String key, Object defaultValue) {
Object value = redisTemplate.opsForValue().get(key);
return value == null ? defaultValue : value;
}
/**
* 向 Redis 中存储一个键值对,并设置其过期时间。
*
* @param key 存储的键
* @param value 存储的值
* @param timeout 过期时间量
* @param timeUnit 时间单位
*/
public void setValueExpiry(String key, Object value, long timeout, TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 向 Redis 中存储一个键值对,并使用 Duration 对象设置其过期时间。
*
* @param key 存储的键
* @param value 存储的值
* @param duration 过期时间范围
*/
public void setValueDuration(String key, Object value, Duration duration) {
redisTemplate.opsForValue().set(key, value, duration);
}
/**
* 从 Redis 中删除指定键及其对应的值。
*
* @param key 要删除的键
*/
public void deleteValue(String key) {
redisTemplate.delete(key);
}
/**
* 检查 Redis 中是否存在指定的键。
*
* @param key 要检查的键
* @return 如果键存在返回 true,否则返回 false
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 获取指定键的剩余过期时间。
*
* @param key 要查询的键
* @return 剩余过期时间,如果键不存在或没有设置过期时间返回 -1
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key);
}
/**
* 获取指定键的剩余过期时间,并指定时间单位。
*
* @param key 要查询的键
* @param timeUnit 时间单位
* @return 剩余过期时间,如果键不存在或没有设置过期时间返回 -1
*/
public long getExpire(String key, TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
/**
* 为已经存在的键设置新的过期时间。
*
* @param key 要设置的键
* @param timeout 过期时间量
* @param timeUnit 时间单位
* @return 如果设置成功返回 true,否则返回 false
*/
public boolean expire(String key, long timeout, TimeUnit timeUnit) {
return redisTemplate.expire(key, timeout, timeUnit);
}
/**
* 为已经存在的键设置新的过期时间,使用 Duration 对象。
*
* @param key 要设置的键
* @param duration 过期时间范围
* @return 如果设置成功返回 true,否则返回 false
*/
public boolean expire(String key, Duration duration) {
return redisTemplate.expire(key, duration);
}
}
后续我们直接使用RedisService,比如:
redisService.setValueDuration(key, value, Duration.ofSeconds(100));