1. 项目依赖配置
Maven依赖
xml
<dependencies>
<!-- Redis Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池依赖(可选但推荐) -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
2. Redis基础配置
application.yml配置
yaml
spring:
redis:
host: localhost
port: 6379
password:
database: 0
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
Redis配置类
java
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用Jackson2JsonRedisSerializer序列化value
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LazyCollectionResolver.instance, ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
3. 基础操作示例
RedisTemplate基本操作
java
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 设置字符串值
*/
public void setString(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 获取字符串值
*/
public String getString(String key) {
Object result = redisTemplate.opsForValue().get(key);
return result != null ? result.toString() : null;
}
/**
* 设置带过期时间的键值对
*/
public void setStringWithExpire(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 删除键
*/
public Boolean deleteKey(String key) {
return redisTemplate.delete(key);
}
/**
* 批量删除键
*/
public Long deleteKeys(Collection<String> keys) {
return redisTemplate.delete(keys);
}
/**
* 判断键是否存在
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 设置过期时间
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
}
Hash操作示例
java
@Service
public class RedisHashService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 向Hash中添加字段
*/
public void putHashField(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* 获取Hash中的字段值
*/
public Object getHashField(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
/**
* 获取整个Hash
*/
public Map<Object, Object> getHashAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 删除Hash中的字段
*/
public Long deleteHashFields(String key, Object... fields) {
return redisTemplate.opsForHash().delete(key, fields);
}
}
4. 缓存注解使用
启用缓存
java
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Service层缓存应用
java
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* 查询用户 - 使用缓存
* @Cacheable: 先查缓存,没有则执行方法并将结果放入缓存
*/
@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
System.out.println("从数据库查询用户: " + id);
return userRepository.findById(id).orElse(null);
}
/**
* 更新用户 - 清除缓存
* @CacheEvict: 清除指定缓存
*/
@CacheEvict(value = "users", key = "#user.id")
public User updateUser(User user) {
System.out.println("更新用户: " + user.getId());
return userRepository.save(user);
}
/**
* 删除用户 - 清除缓存
*/
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
System.out.println("删除用户: " + id);
userRepository.deleteById(id);
}
/**
* 清除所有用户缓存
* @CacheEvict(allEntries = true): 清除所有缓存
*/
@CacheEvict(value = "users", allEntries = true)
public void clearAllUserCache() {
System.out.println("清除所有用户缓存");
}
}
自定义缓存Key生成策略
java
@Component
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getSimpleName());
sb.append("_");
sb.append(method.getName());
for (Object obj : params) {
sb.append("_");
sb.append(obj.toString());
}
return sb.toString();
}
}
// 使用自定义Key生成器
@Cacheable(value = "users", keyGenerator = "customKeyGenerator")
public List<User> findAllUsers() {
return userRepository.findAll();
}
5. Session共享配置
Session配置
java
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
}
6. 分布式锁实现
Redis分布式锁工具类
java
@Component
public class RedisDistributedLock {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String LOCK_PREFIX = "lock:";
private static final int DEFAULT_EXPIRE_TIME = 30; // 默认过期时间(秒)
/**
* 获取分布式锁
*/
public boolean lock(String key, String value, int expireTime) {
String lockKey = LOCK_PREFIX + key;
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS);
return result != null && result;
}
/**
* 释放分布式锁
*/
public boolean unlock(String key, String value) {
String lockKey = LOCK_PREFIX + key;
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Boolean result = redisTemplate.execute(new DefaultRedisScript<>(script, Boolean.class),
Collections.singletonList(lockKey), value);
return result != null && result;
}
}
7. 性能监控配置
Redis监控配置
java
@Configuration
public class RedisMonitorConfig {
@Bean
public RedisTemplate<String, Object> monitoredRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
@EventListener
public void handleRedisMessage(RedisMessageEvent event) {
// 监控Redis消息事件
System.out.println("Redis事件: " + event.getMessage());
}
}
8. 最佳实践建议
配置优化要点:
- 连接池配置:合理设置最大连接数和空闲连接数
- 序列化方式:推荐使用JSON序列化替代默认的JDK序列化
- 超时设置:设置合适的连接和读取超时时间
- 缓存失效策略:根据业务场景设置合理的过期时间和淘汰策略
注意事项:
- 缓存穿透:对于查询不到的数据也要缓存空值
- 缓存雪崩:避免大量缓存在同一时间失效
- 缓存击穿:热点数据使用互斥锁保护
- 内存管理:定期清理无用缓存,防止内存溢出
这样的整合方案能够满足大部分Spring Boot项目的Redis使用需求,并提供了良好的扩展性和维护性。