【在Spring Boot中集成Redis】

依赖

		<!-- Spring对Redis的集成支持 -->
     	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 阿里JSON解析器 -->
    	<dependency>
        	<groupId>com.alibaba.fastjson2</groupId>
        	<artifactId>fastjson2</artifactId>
   	 	</dependency>

在application.yml中配置Redis服务地址

spring:
  profiles:
    active: druid
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    database: 0
    timeout: 1800000

Redis 序列化器

package com.chinabuilder.framework.config;

/**
 * FastJson2 实现的 Redis 序列化器
 *
 * 功能:将 Java 对象与 Redis 存储的二进制数据相互转换,使用 FastJson2 作为序列化工具。
 * 特点:
 *   1. 支持类名白名单过滤,防止反序列化攻击(安全特性)
 *   2. 自动处理 null 值和空字节数组
 *   3. 使用 UTF-8 编码确保跨平台兼容性
 *   4. 序列化时写入类名(WriteClassName),便于反序列化时类型识别
 *
 * 泛型说明:
 *   @param <T> 需序列化的对象类型,需与反序列化目标类型一致
 *
 * 示例用法:
 *   RedisTemplate<String, User> template = new RedisTemplate<>();
 *   template.setValueSerializer(new FastJson2JsonRedisSerializer<>(User.class));
 */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
    /**
     * 默认字符集:UTF-8
     * 确保序列化后的字节在不同系统间兼容
     */
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    /**
     * 类名白名单过滤器
     * 通过 {@link Constants.JSON_WHITELIST_STR} 配置允许反序列化的类全限定名
     * 示例白名单内容:["com.example.Entity", "java.util.ArrayList"]
     */
    static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);

    /**
     * 目标类型的 Class 对象
     * 用于反序列化时确定具体类型
     */
    private Class<T> clazz;

    public FastJson2JsonRedisSerializer(Class<T> clazz)
    {
        // 调用父类的无参构造函数。
        // 它是子类构造函数中的第一行代码(如果不显式写,编译器会自动插入,前提是父类有无参构造函数)。
        // 目的是确保父类的初始化逻辑先于子类执行。
        super();
        this.clazz = clazz;
    }

    /**
     * 序列化方法:将 Java 对象转换为字节数组
     *
     * @param t 待序列化的对象,允许为 null
     * @return 序列化后的字节数组,null 对象返回空数组(非 null)
     * @throws SerializationException 序列化失败时抛出
     *
     * 关键逻辑:
     * 1. 空值检查:直接返回空数组,避免 NPE
     * 2. 使用 FastJson2 的 {@link JSONWriter.Feature.WriteClassName} 特性,
     *    在 JSON 中写入类名,确保反序列化能识别原始类型
     * 3. 转换为 UTF-8 字节数组
     */
    @Override
    public byte[] serialize(T t) throws SerializationException
    {
        if (t == null)
        {
            return new byte[0];
        }
        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }
    /**
     * 反序列化方法:将字节数组还原为 Java 对象
     *
     * @param bytes 待反序列化的字节数组,允许为 null 或空数组
     * @return 反序列化后的对象,输入为空时返回 null
     * @throws SerializationException 反序列化失败时抛出(如白名单校验不通过)
     *
     * 关键逻辑:
     * 1. 空值检查:直接返回 null
     * 2. 将字节数组转为 UTF-8 字符串
     * 3. 使用 {@link #AUTO_TYPE_FILTER} 白名单过滤,仅允许预定义的类被反序列化
     * 4. 通过目标类型 clazz 确保反序列化结果类型安全
     *
     * 安全说明:
     * - 白名单机制可防御 Fastjson 的 autoType 漏洞(如恶意类加载)
     * - 若 bytes 包含非白名单类名,会抛出 {@link com.alibaba.fastjson2.JSONException}
     */
    @Override
    public T deserialize(byte[] bytes) throws SerializationException
    {
        if (bytes == null || bytes.length <= 0)
        {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        // 反序列化(启用白名单过滤)
        return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
    }
}

初始化配置RedisConfig

package com.chinabuilder.framework.config;

/**
 * Redis配置类
 *
 * 该类配置了Redis的核心功能
 * RedisTemplate的序列化配置
 */
@Configuration
@EnableCaching // 启用Spring缓存注解支持
public class RedisConfig extends CachingConfigurerSupport
{
    /**
     * 配置RedisTemplate
     *
     * @param connectionFactory Redis连接工厂
     * @return 配置好的RedisTemplate实例
     */
    @Bean
    @SuppressWarnings(value = { "unchecked", "rawtypes" })
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
    {
        // 创建RedisTemplate实例
        RedisTemplate<Object, Object> template = new RedisTemplate<>();

        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);

        // 创建FastJson2序列化器,用于值(value)的序列化
        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);


        // 设置键(key)的序列化器为StringRedisSerializer 确保所有键以字符串形式存储
        // 避免二进制键导致 Redis 命令行工具无法直接查看
        template.setKeySerializer(new StringRedisSerializer());

        // 设置值(value)的序列化器为FastJson2JsonRedisSerializer
        // 用于复杂对象的序列化
        template.setValueSerializer(serializer);

        // 设置Hash结构的key的序列化器
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置Hash结构的value的序列化器
        template.setHashValueSerializer(serializer);

        // 初始化模板属性
        template.afterPropertiesSet();

        return template;
    }

}

缓存工具类

/**
 * spring redis 工具类
 *
 **/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache {
    @Autowired
    public RedisTemplate redisTemplate;

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout) {
        return expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 获取有效时间
     *
     * @param key Redis键
     * @return 有效时间
     */
    public long getExpire(final String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 判断 key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 删除单个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public boolean deleteObject(final Collection collection) {
        return redisTemplate.delete(collection) > 0;
    }
}

使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值