Redis序列化以及封装类

本文介绍了如何在SpringBoot项目中配置RedisTemplate进行序列化,并提供了一个封装了Redis操作的工具类,包括缓存读写、过期时间管理等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实现Redis的序列化

@Configuration
public class RedisConfig {
    @Bean(name = "redisTemplate")
    public RedisTemplate<String,Object> getRedisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();
        redisTemplate.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);  //key的序列化类型

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);     //value的序列化类型
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

2.封装工具类

package com.example.redis;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedisUtils {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 读取缓存 redis中key对应的值
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        return redisTemplate.opsForValue().get(key);
    }


    /**
     * 写入String类型 到redis
     */
    public boolean set(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value);
            log.info("存入redis成功,key:{},value:{}", key, value);
            result = true;
        } catch (Exception e) {
            log.info("存入redis失败,key:{},value:{}", key, value);
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 写入对象到redis      Json格式
     */
    public boolean setJsonString(final String key, Object value) {
        if (StringUtils.isBlank(key)) {
            log.info("redis key值为空");
            return false;
        }
        try {
            redisTemplate.opsForValue().set(key, JSON.toJSONString(value));
            log.info("存入redis成功,key:{},value:{}", key, value);
            return true;
        } catch (Exception e) {
            log.info("存入redis失败,key:{},value:{}", key, value);
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 更新缓存
     */
    public boolean getAndSet(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().getAndSet(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 删除缓存
     */
    public boolean delete(final String key) {
        boolean result = false;
        try {
            redisTemplate.delete(key);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 一个指定的 key 设置过期时间
     *
     * @param key
     * @param time
     */
    public boolean expire(String key, long time) {
        return redisTemplate.expire(key, time, TimeUnit.SECONDS);
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key
     */
    public long getTime(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key
     */
    public boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 移除指定key 的过期时间
     *
     * @param key
     */
    public boolean persist(String key) {
        return redisTemplate.boundValueOps(key).persist();
    }


    /**
     * 将数据放入set缓存
     *
     * @param key 键
     */
    public void sSet(String key, String value) {
        redisTemplate.opsForSet().add(key, value);
    }
}

### Redis 序列化方法及配置 #### Jackson 和 Redis 的集成 为了使 Spring Boot 项目中的 Redis 能够正确处理 Java 对象的存储与读取,Jackson 是一种常用的 JSON 处理库。通过自定义 `ObjectMapper` 并设置默认类型信息的方式可以确保对象及其子类型的完整序列化[^1]。 当使用如下代码片段时: ```java objectMapper.activateDefaultTyping( LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); ``` 这段代码的作用在于激活默认类型识别机制,并指定以数组形式包裹整个 JSON 字符串来保存类名信息。这使得即使是从 Redis 取回的数据也能被准确无误地映射回原始的对象结构而不是简单的 `LinkedHashMap` 实例。 对于最终用户来说,这意味着任何继承自非 final 基础类的具体实现都可以安全地存入并取出而不会丢失其实际类型的信息。然而需要注意的是,final 类型属性并不会参与此过程;因此这些字段将按照常规方式进行序列化/反序列化操作而不附加额外元数据。 #### 配置方式的选择 在决定采用哪种序列化策略之前,应该考虑应用程序的需求以及性能因素。例如,虽然上述提到的方法能够很好地支持多态性场景下的对象持久化需求,但它可能会增加一些开销因为每条记录都需要携带完整的类型描述信息。相比之下,其他更轻量级或者特定于应用领域模型的设计也可能更加合适取决于具体的应用环境和业务逻辑复杂度。 另外值得注意的一点是,如果选择了不同的封装风格如 `WRAPPER_OBJECT` 来代替 `WRAPPER_ARRAY`,那么所得到的结果将会是以大括号包围的形式而非方括号[]。这种差异可能会影响到后续解析阶段的行为模式,所以在做决策前应当充分评估各种选项带来的影响。 #### 如何实现正确的序列化配置 要实现在 Spring Boot 中利用 Jackson 完成对 Redis 数据源的有效管理,可以通过扩展 `RedisTemplate` 或者创建自己的序列化工厂来完成定制工作。下面是一个简单例子展示了如何注册一个带有特殊配置项(即上面讨论过的)的 `ObjectMapper` 给到模板实例上: ```java @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); // 设置序列化器 Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.activateDefaultTyping( LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY ); serializer.setObjectMapper(objectMapper); template.setValueSerializer(serializer); template.afterPropertiesSet(); return template; } ``` 以上代码段实现了为 Redis 模板指定了基于 Jackson 的 JSON 序列化工具链,并启用了必要的类型保留特性以便更好地兼容复杂的对象图谱结构。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值