Spring Boot 2.x 项目中使用Redis缓存封装 (持续更新中....)
Spring Boot 2.x 项目中使用Redis缓存封装
项目中多使用Redis缓存,团队协作中Redis代码经常重复,并且不规范,这里封装RedisService用做公共服务通过继承的方式调用
1.Redis 开发规范
- 【建议】Key名称设计
以业务名称(或数据库名)为前缀(防止Key冲突) ,用冒号进行分割,比如 项目名:业务属性:id
security-tech:course:1
-
【建议】简洁性
保证语义的前提下,控制key的长度,当key较多的是都,内存占用不容忽视 -
【强制】不要包含特殊字符
返利:包含空格、换行、单双一号以及其他转义字符 -
【强制】控制key的生命周期
建议使用expire设置过期时间(条件允许可以打散过期时间,方式key集中过期),不过期的数据重点关注idletime。
2. Spring Boot 集成Redis
2.1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2 增加Config配置
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author shiyu.du
* @date 2020/10/13
* @describe
*/
@Configuration
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisSerializer")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisSerializer<Object> serializer = redisSerializer();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisSerializer<Object> redisSerializer(){
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(objectMapper);
return serializer;
}
}
2.3 Reids 封装代码
import cn.hutool.core.util.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis 缓存Service
*
* @author Syer
*/
@Component
public abstract class RedisCacheService {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisCacheService.class);
@Value("${spring.application.name}")
private String applicationName;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 添加缓存
*
* @param key key
* @param value value
*/
protected void set(String key, Object value) {
LOGGER.info("[ RedisCacheService ] 添加 Redis 缓存 Key :[{}] , Value: [{}]", key, value);
redisTemplate.opsForValue().set(key, value);
}
/**
* 添加缓存(失效时间)
*
* @param key key
* @param value value
* @param duration 时效
* @param timeUnit 时间类型
*/
protected void set(String key, Object value, Integer duration, TimeUnit timeUnit) {
LOGGER.info("[ RedisCacheService ] 添加 Redis 缓存 Key :[{}] , Value: [{}] , Duration:[{}] , TimeUnit: [{}]", key, value, duration, timeUnit);
redisTemplate.opsForValue().set(key, value, duration, timeUnit);
}
/**
* 获取缓存值
*
* @param key key
* @return 返回值 Object
*/
protected Object get(String key) {
LOGGER.info("[ RedisCacheService ] 获取 Redis 缓存 Key :[{}] ", key);
return redisTemplate.opsForValue().get(key);
}
/**
* 获取缓存值,缓存值为空返回默认值
*
* @param key key
* @param defaultValue 默认值
* @return 缓存值 Object
*/
protected Object getOrDefault(String key, Object defaultValue) {
Object cacheValue = this.get(key);
if (ObjectUtil.isNotEmpty(cacheValue)) {
LOGGER.info("[ RedisCacheService ] 获取 Redis 缓存 Key :[{}] ", key);
return cacheValue;
}
LOGGER.info("[ RedisCacheService ] 获取 Redis 缓存 Key :[{}] Value 不存在返回默认值", key);
return defaultValue;
}
/**
* 删除缓存
*
* @param key key
*/
protected void remove(String key) {
LOGGER.info("[ RedisCacheService ] 删除 Redis 缓存 Key :[{}] ", key);
redisTemplate.delete(key);
}
/**
* Redis 原子性自增方法
*
* @param key 缓存key
* @param incrementNum 自增数量
* @return 增长后的值
*/
protected Long incr(String key, Long incrementNum) {
LOGGER.info("[ RedisCacheService ] 自增 Redis 缓存 Key :[{}] 增加数量:[{}]", key, incrementNum);
return redisTemplate.opsForValue().increment(key, incrementNum);
}
/**
* Redis List 模型 推送
*
* @param key 缓存key
* @param value value
*/
protected void push(String key, Object value) {
redisTemplate.opsForList().rightPush(key, value);
}
/**
* Redis List 获取
*
* @param key key
* @return obj
*/
protected Object pollRight(String key) {
return redisTemplate.opsForList().rightPop(key);
}
/**
* Redis ZSet 添加
*
* @param key 统一标识
* @param primaryKey 唯一标识
* @param score 分数
*/
protected void zsetAdd(String key, String primaryKey, Double score) {
redisTemplate.opsForZSet().add(key, primaryKey, score);
}
/**
* Redis ZSet 指定成员Rank 排行
*
* @param key 统一标识
* @param primaryKey 唯一标识
*/
protected Long zsetRank(String key, String primaryKey) {
return redisTemplate.opsForZSet().rank(key, primaryKey);
}
/**
* 获取分数
*
* @param key 统一标识
* @param primaryKey 唯一标识
* @return
*/
protected Double zsetRankScore(String key, String primaryKey) {
return redisTemplate.opsForZSet().score(key, primaryKey);
}
/**
* Redis ZSet 移除
*
* @param key 统一标识
* @param primaryKey 唯一标识
*/
protected void zsetRemove(String key, String primaryKey) {
redisTemplate.opsForZSet().remove(key, primaryKey);
}
/**
* Redis ZSet 为指定元素加分
*
* @param key 统一标识
* @param primaryKey 唯一标识
* @param incrScore 增长分数
*/
protected void zsetIncr(String key, String primaryKey, Double incrScore) {
redisTemplate.opsForZSet().incrementScore(key, primaryKey, incrScore);
}
/**
* 获取rank 情况Reverse 从大到小
*
* @param key 统一标识
* @return Set<Object>
*/
protected Set<Object> zsetListReverse(String key, Integer startIndex, Integer endIndex) {
return redisTemplate.opsForZSet().reverseRange(key, startIndex, endIndex);
}
/**
* Set 模型添加数据
*
* @param key 统一标识
* @param value 值
*/
protected void setAdd(String key, Object value) {
redisTemplate.opsForSet().add(key, value);
}
/**
* Set 模式 检查给定的元素是否在变量中
*
* @param key 缓存Key
* @param value value
* @return 存在 true 不存在 false
*/
protected Boolean setIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* Set 模式 获取变量中的值
*
* @param key 缓存Key
* @return 所有值
*/
protected Set<Object> setMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 包装缓存Key
*
* @param prefix 缓存前缀
* @param primaryKey 唯一值
* @return 缓存Key (string)
*/
protected String wrapperKey(String prefix, Object primaryKey) {
String cacheKey = this.applicationName + prefix + primaryKey;
LOGGER.info("[ RedisCacheService ] 生成缓存Key:[{}]", cacheKey);
return cacheKey;
}
}

浙公网安备 33010602011771号