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;
    }
}

posted @ 2021-07-12 14:31  SyerDu  阅读(351)  评论(0)    收藏  举报