【小家Spring】Redis序列化、RedisTemplate序列化方式大解读,介绍Genericjackson2jsonredisserializer序列化器的坑(下)

简介: 【小家Spring】Redis序列化、RedisTemplate序列化方式大解读,介绍Genericjackson2jsonredisserializer序列化器的坑(下)

解决方案


既然你需要GenericJackson2JsonRedisSerializer它的通用性,那么你就得接受他只能处理Object类型。


因此在使用的时候遇上这种情况,需要稍加注意了。我们可以先用Object接收,然后转成字符串再调用Long.valueOf()方法去间接实现。。。或者你在使用前手动指定序列化类型,但十分、十分不建议这么去做


它处理List、Set、Long类型等都会有类似的问题。使用的时候稍加注意即可(因为Java中默认数字类型是Integer、Double等)


当然还有一种方案是自定义序列化器:如自定义String序列化器,接受一切类型(官方的泛型限制了只接受String类型。这么一来,@Cacheable等注解的key支持不仅仅是String类型了):

/**
 * 必须重写序列化器,否则@Cacheable注解的key会报类型转换错误
 */
public class StringRedisSerializer implements RedisSerializer<Object> {
    private final Charset charset;
    private final String target = "\"";
    private final String replacement = "";
    public StringRedisSerializer() {
        this(Charset.forName("UTF8"));
    }
    public StringRedisSerializer(Charset charset) {
        Assert.notNull(charset, "Charset must not be null!");
        this.charset = charset;
    }
    @Override
    public String deserialize(byte[] bytes) {
        return (bytes == null ? null : new String(bytes, charset));
    }
    @Override
    public byte[] serialize(Object object) {
        //底层还是调用的fastjson的工具来操作的
        String string = JSON.toJSONString(object);
        if (string == null) {
            return null;
        }
        string = string.replace(target, replacement);
        return string.getBytes(charset);
    }
}


顺便提一句:单元测试的时候可能碰上这个异常:WRONGTYPE Operation against a key holding the wrong kind of value,不要慌。这个是因为key的类型不一致导致,一般只有在测试情况下才会发生**。比如之前这个key用用作k-v的形式,现在把这个key当作set数据类型来用,就会报这个错,换给key就行。**


说明:Jackson2JsonRedisSerializer的效率稍微优于GenericJackson2JsonRedisSerializer,但是使用起来远没有Generic方便。

各位看官可以根据自己业务的实际情况,酌情选择吧~~~~

第三方序列化器:FastJsonRedisSerializer、KryoRedisSerializer


由于Redis的流行,很多第三方组件都提供了对应的序列化器。比较著名的有阿里巴巴的FastJsonRedisSerializer


还好ali默认已经帮我们实现了基于fastjson的序列化方式,我们都不用自己动手了。

FastJsonRedisSerializer和GenericFastJsonRedisSerializer

和上面一样讲述的一样,FastJsonRedisSerializer需要指定反序列化类型,而GenericFastJsonRedisSerializer则比较通用。但同样的Generic系列存在上面我说的同样的问题,大家使用时需要多加注意。


KryoRedisSerializer:它就没有这么这么友好了,但自己实现一个也是轻而易举的事:


public class KryoRedisSerializer<T> implements RedisSerializer<T> {
    private Kryo kryo = new Kryo();
    @Override
    public byte[] serialize(T t) throws SerializationException {
        System.out.println("[serialize]" + t);
        byte[] buffer = new byte[2048];
        Output output = new Output(buffer);
        kryo.writeClassAndObject(output, t);
        return output.toBytes();
    }
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        System.out.println("[deserialize]" + Arrays.toString(bytes));
        Input input = new Input(bytes);
        @SuppressWarnings("unchecked")
        T t = (T) kryo.readClassAndObject(input);
        return t;
    }
}

指定RedisTemplate的序列化方式



这个就比较简单了,可以在注册Bean的时候就set(推荐),也可以使用的时候再做(非常非常不推荐,会有并发安全问题)


    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认序列化(备注,此处我用Object为例,各位看官请换成自己的类型哦~)
        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);
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 最好是调用一下这个方法
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }


java源生序列化的效率已经非常高了,但是kryo是java原生序列化性能十几倍(kryo只针对java语言,不跨语言。跨语言的序列化方式有:Protostuff、Thrift等。 所以如果你想自定义序列化器的话,个人建议可以导入kryo包,然后自己书写一个序列化器注册进去~~~)

相关文章
|
4月前
|
存储 NoSQL Java
配置RedisTemplate序列化机制
通过上述步骤,你可以灵活配置RedisTemplate的序列化机制,根据应用需求选择合适的序列化器,从而确保数据在Redis中的存储和读取效率最优化。配置合适的序列化机制对于性能和存储效率至关重要,而且这样可以确保数据在存储和传输过程中的结构清晰和一致性。
316 11
|
9月前
|
NoSQL 安全 Java
深入理解 RedisConnectionFactory:Spring Data Redis 的核心组件
在 Spring Data Redis 中,`RedisConnectionFactory` 是核心组件,负责创建和管理与 Redis 的连接。它支持单机、集群及哨兵等多种模式,为上层组件(如 `RedisTemplate`)提供连接抽象。Spring 提供了 Lettuce 和 Jedis 两种主要实现,其中 Lettuce 因其线程安全和高性能特性被广泛推荐。通过手动配置或 Spring Boot 自动化配置,开发者可轻松集成 Redis,提升应用性能与扩展性。本文深入解析其作用、实现方式及常见问题解决方法,助你高效使用 Redis。
1015 4
|
4月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
372 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
10月前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
400 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
5月前
|
存储 NoSQL Java
RedisTemplate序列化问题排查与优化建议。
最后,对于序列化问题的深入排查与优化,建议编写具有代表性的单元测试,以验证RedisTemplate配置的正确性和效能。此外,可以在非生产环境中测试不同的序列化策略,找到最适合当前应用场景的序列化方式。通过不断迭代和优化,达到持续提高数据存取能力的目标。
277 13
|
6月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
638 2
|
8月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
295 32
|
10月前
|
NoSQL Java API
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Spring Boot 集成 Redis
本文介绍了在Spring Boot中集成Redis的方法,包括依赖导入、Redis配置及常用API的使用。通过导入`spring-boot-starter-data-redis`依赖和配置`application.yml`文件,可轻松实现Redis集成。文中详细讲解了StringRedisTemplate的使用,适用于字符串操作,并结合FastJSON将实体类转换为JSON存储。还展示了Redis的string、hash和list类型的操作示例。最后总结了Redis在缓存和高并发场景中的应用价值,并提供课程源代码下载链接。
2427 0
|
10月前
|
NoSQL Java Redis
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 安装
本教程介绍在 VMware 虚拟机(CentOS 7)或阿里云服务器中安装 Redis 的过程,包括安装 gcc 编译环境、下载 Redis(官网或 wget)、解压安装、修改配置文件(如 bind、daemonize、requirepass 等设置)、启动 Redis 服务及测试客户端连接。通过 set 和 get 命令验证安装是否成功。适用于初学者快速上手 Redis 部署。
332 0
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
860 5