Redis在SpringBoot中的基本使用_springboot中redis配置
1、引入Maven依赖
首先,需要在 pom.xml 文件中添加 Redis 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
这个依赖包含了 Spring Data Redis,以及 Jedis 和 Lettuce 这两种 Redis 客户端的实现。
如果使用Lettuce作为连接池(推荐),还需要添加:
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
2、配置Redis连接
在 SpringBoot 项目中,可以通过在 application.properties 或 application.yml 文件中配置 Redis 连接信息。以下是一个示例:
# Redis基本配置
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
# 连接池配置(Lettuce)
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-wait=-1ms
其中,host 和 port 分别是 Redis 服务器的地址和端口号,password 是 Redis的密码(如果没有密码,可以不填),timeout 是 Redis 连接超时时间,jedis.pool 是连接池的相关设置。
3、创建RedisTemplate
使用 Spring Data Redis 操作 Redis,通常会使用 RedisTemplate 类。为了方便起见,我们可以创建一个工具类来管理 RedisTemplate 的创建和使用。以下是一个示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
/**
* 如果使用 @Autowired 注解完成自动装配 那么
* RedisTemplate要么不指定泛型,要么泛型 为<Stirng,String> 或者<Object,Object>
* 如果你使用其他类型的 比如RedisTemplate<String,Object>
* 那么请使用 @Resource 注解
* */
@Resource
private RedisTemplate<String,Object> redisTemplate;
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 缓存value
* @param key -
* @param value -
* @param time -
* @return -
*/
public boolean cacheValue(String key, Object value, long time) {
try {
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
valueOperations.set(key, value);
if (time > 0) {
// 如果有设置超时时间的话
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Throwable e) {
logger.error("缓存[" + key + "]失败, value[" + value + "] " + e.getMessage());
}
return false;
}
/**
* 缓存value,没有设置超时时间
*
* @param key -
* @param value -
* @return -
*/
public boolean cacheValue(String key, Object value) {
return cacheValue(key, value, -1);
}
/**
* 判断缓存是否存在
*
* @param key
* @return
*/
public boolean containsKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Throwable e) {
logger.error("判断缓存是否存在时失败key[" + key + "]", "err[" + e.getMessage() + "]");
}
return false;
}
/**
* 根据key,获取缓存
*
* @param key -
* @return -
*/
public Object getValue(String key) {
try {
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
return valueOperations.get(key);
} catch (Throwable e) {
logger.error("获取缓存时失败key[" + key + "]", "err[" + e.getMessage() + "]");
}
return null;
}
/**
* 移除缓存
*
* @param key -
* @return -
*/
public boolean removeValue(String key) {
try {
redisTemplate.delete(key);
return true;
} catch (Throwable e) {
logger.error("移除缓存时失败key[" + key + "]", "err[" + e.getMessage() + "]");
}
return false;
}
/**
* 根据前缀移除所有以传入前缀开头的key-value
*
* @param pattern -
* @return -
*/
public boolean removeKeys(String pattern) {
try {
Set<String> keySet = redisTemplate.keys(pattern + "*");
redisTemplate.delete(keySet);
return true;
} catch (Throwable e) {
logger.error("移除key[" + pattern + "]前缀的缓存时失败", "err[" + e.getMessage() + "]");
}
return false;
}
}
在这个示例中,我们使用 @Resource 注解自动注入了一个 RedisTemplate<String, Object> 对象。然后,我们提供了三个方法来对 Redis 进行操作:cacheValue 方法用于缓存数据,getValue 方法用于获取缓存数据,removeValue 方法用于删除缓存数据。这些方法都是通过 redisTemplate 对象来实现的。
需要注意的是,在使用 RedisTemplate 时,需要指定键值对的类型。在这个示例中,我们指定了键的类型为 String,值的类型为 Object。
4、使用RedisTemplate
在上面的示例中,我们已经创建了一个 RedisTemplate 对象,并提供了一些方法来对 Redis 进行操作。现在,我们可以在 SpringBoot 项目中的任何地方使用这个工具类来进行缓存操作。以下是一个示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private RedisUtils redisUtils;
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
String key = "user_" + id;
User user = (User) redisUtils.getValue(key);
if (user == null) {
user = userService.getUserById(id);
redisUtils.cacheValue(key, user);
}
return user;
}
}
在这个示例中,我们创建了一个 UserController 类,用于处理 HTTP 请求。在 getUserById 方法中,我们首先构造了一个缓存的 key,然后使用 redisUtils.getValue 方法从 Redis 中获取缓存数据。如果缓存中没有数据,我们调用 userService.getUserById 方法从数据库中获取数据,并使用 redisUtils.cacheValue 方法将数据存入Redis缓存中。最后,返回获取到的数据。
5、使用Spring Cache注解
Spring Boot提供了缓存抽象,可以很方便地使用注解来实现缓存:
- 启用缓存支持:
@SpringBootApplication
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
- 使用缓存注解:
@Service
public class UserService {
// 方法结果缓存,key为参数id
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
// 模拟数据库查询
return findUserInDB(id);
}
// 更新缓存
@CachePut(value = "user", key = "#user.id")
public User updateUser(User user) {
// 更新数据库
return updateUserInDB(user);
}
// 删除缓存
@CacheEvict(value = "user", key = "#id")
public void deleteUser(Long id) {
// 从数据库删除
deleteUserInDB(id);
}
}
6、自定义Redis序列化方式
默认情况下,RedisTemplate使用
JdkSerializationRedisSerializer,可以自定义序列化方式:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
7、 分布式锁实现
使用Redis实现简单的分布式锁:
public class RedisLock {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 加锁
* @param key 锁的key
* @param value 请求标识(通常使用UUID)
* @param expireTime 过期时间(秒)
* @return 是否获取成功
*/
public boolean lock(String key, String value, long expireTime) {
Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);
return Boolean.TRUE.equals(result);
}
/**
* 释放锁
* @param key 锁的key
* @param value 请求标识
* @return 是否释放成功
*/
public boolean unlock(String key, String value) {
String currentValue = redisTemplate.opsForValue().get(key);
if (currentValue != null && currentValue.equals(value)) {
redisTemplate.delete(key);
return true;
}
return false;
}
}
通过以上方式,可以在Spring Boot项目中轻松集成Redis,实现缓存、分布式锁等功能,提升应用性能。