• Spring Boot | Spring Boot “自定义“ Redis缓存 “序列化机制“



    在这里插入图片描述

    作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

    该文章参考学习教材为:
    《Spring Boot企业级开发教程》 黑马程序员 / 编著
    文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

    文章用于本人学习使用 , 同时希望能帮助大家。
    欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

    (侵权可联系我,进行删除,如果雷同,纯属巧合)


    Spring Boot “自定义” Redis缓存 “序列化机制” :

    一、基于 “注解” 的 “Redis缓存管理” 的 “默认序列化机制” 和 “自定义序列化机制”

    1.1 基于 “注解” 的 “Redis缓存管理” 的 “默认序列化机制”

    • 基于 “注解” 的 “Redis缓存管理” 中我们已经实现了在 Spring Boot 中使用 Redis 来进行 数据 “缓存管理”,此时 缓存管理 的使用的 序列化机制为 : JDK 序列化机制 ,如下图所示

      ( Redis API默认序列化机制 为 : JDK序列化机制 )。

      在这里插入图片描述

      可通过 JSON格式的 "序列化机制"解决这个问题

    1.2 自定义 基于"注解" “Redis缓存管理” 的 “序列化机制” ( 自定义一个 “RedisCacheManager对象” , 在该对象中进行 “序列化” 的 “自定义” )

    • 打开 Spring Boot 整合 Redis 组件提供的缓存自动配置类RedisCacheConfiguration (org.springframework.boot.autoconfigure.cache 下的),查看该类源码信息,其 核心代码 如下 :

      package org.springframework.boot.autoconfigure.cache;
      
      @Configuration
      class RedisCacheConfiguration {
      
          @Bean
          public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
            RedisCacheManagerBuilder builder =            RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader()));
              List<String> cacheNames = cacheProperties.getCacheNames();
               if (!cacheNames.isEmpty()) {
                  builder.initialCacheNames(new LinkedHashSet(cacheNames));
              }
                return (RedisCacheManager)cacheManagerCustomizers.customize(builder.build());
          }
              .....
      
            private org.springframework.data.redis.cache.RedisCacheConfiguration createConfiguration(ClassLoader classLoader) {
              CacheProperties.Redis redisProperties = cacheProperties.getRedis();
              org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
              config = config.serializeValuesWith(SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader))); 
              .....
              return config;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24

      上述核心源码中可以看出,同 RedisTemplate 核心源码 类似RedisCacheConfiguration 内部同样通过 RedisConnectionFactory ( Redis连接工厂 ) 定义了一个 RedisCacheManager ( 缓存管理器 ) ; 同时定制 RedisCacheManager 时,使用了 默认JdkSerializationRedisSerializer ( JDK序列化机制 ) 。


      如果想要使用 自定义序列化方式RedisCacheManager进行数据缓存操作,可以参考上述核心代码创建一个名为 cacheManager
      Bean组件,并在该组件设置对应序列化方式 即可。

    • 通过 自定义 RedisCacheManager对象 来 “自定义序列化机制” ( 自定义 基于 “注解” 的 “Redis缓存管理” 的 “序列化机制” ) :

      RedisConfig.java : ( 添加配置类,即可实现 JSON序列化机制 )

      import com.fasterxml.jackson.annotation.JsonAutoDetect;
      import com.fasterxml.jackson.annotation.PropertyAccessor;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.cache.RedisCacheConfiguration;
      import org.springframework.data.redis.cache.RedisCacheManager;
      import org.springframework.data.redis.connection.RedisConnectionFactory;
      import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
      import org.springframework.data.redis.serializer.RedisSerializationContext;
      import org.springframework.data.redis.serializer.RedisSerializer;
      import org.springframework.data.redis.serializer.StringRedisSerializer;
      
      import java.time.Duration;
      
      @Configuration //标记该类为"配置类"
      public class RedisConfig { 
      
          @Bean
          public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
              //分别创建String 和 JSON格式的 "序列化对象" , 对缓存数据key和value进行转换
              /**
               * "String格式序列化机制" ---用在存储的"缓存数据"的key
               */
              RedisSerializer<String> strSerializer = new StringRedisSerializer();
      
              //解决查询缓存转换异常的问题
              ObjectMapper objectMapper  = new ObjectMapper();
              objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
              objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
              /*
                使用"JSON格式序列化机制" 对缓存数据key和value进行转换 ---用在存储的"缓存数据"的value
               */
              Jackson2JsonRedisSerializer jsonSerializer = new Jackson2JsonRedisSerializer(objectMapper,Object.class);
      
              /*
               定制"缓存数据序列化方式"及"时效"
               */
              RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                      .entryTtl(Duration.ofDays(1)) //"缓存数据"的"持续时效"
                      .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(strSerializer))//设置key的"序列化机制"
                      .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer))//设置value的"序列化机制"
                      .disableCachingNullValues();
      
              //创建RedisCacheManager对象
              RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
              return redisCacheManager;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49

      上述代码中,在 RedisConfig 配置类中使用 @Bean 注解注入了一个默认名称方法名cacheManager 组件
      定义的 Bean 组件中,通过 RedisCacheConfiguration 对缓存数据的 keyvalue 分别进行了序列化方式的定制,其中缓存数据的 key定制为 StringRedisSerializer(即String 格式),而 value 定制为了 Jackson2JsonRedisSerializer(即 JSON 格式 ),同时还使用entryTtl ( Duration.ofDays(1) ) 方法将 缓存数据有效期 设置为 1天。最后创建 RedisCacheManager对象


      基于 “注解” 的 “Redis缓存管理” ,在 左边的项目代码基础上添加 RedisConfig.java 配置类启动该项目访问ulr,可以看到 Redis数据库 中的数据为 JSON格式 ( 如下图所示 ),便于查看和管理,表明其实 序列化方式为 : JSON序列化方式

      在这里插入图片描述

    二、Redis API ( RedisTemplate类 ) 的 “默认序列化机制” 和 “自定义序列化机制”

    2.1 Redis API ( RedisTemplate类 ) 的 “默认序列化机制”

    • 基于 “API” ( RedisTemplate类 ) 的 “Redis缓存管理” 中我们已经实现了在 Spring Boot 中使用 Redis 来进行 数据
      “缓存管理”,此时 缓存管理的使用的 序列化机制 为 : JDK 序列化机制

      ( Redis API默认序列化机制 为 : JDK序列化机制 )。

    • JDK 序列化机制缺点 :

      实体类中 要 实现 "Serializable接口" ,以此对数据进行"序列化"。

      不便于使用可视化管理工具进行查看管理 ( 即此时Redis数据库可视化界面看到都是一些 Hex 格式的数据 ( 或者 二进制格式 / 其他格式 ),都 不是一些明细可视化的数据 ),如下图所示

      在这里插入图片描述

      可通过 JSON格式的 "序列化机制"解决这个问题

    2.2 自定义 Redis API ( RedisTemplate类 ) 的 “序列化机制” ( 自定义一个"RedisTemplate"对象,在该对象中进行 “序列化” 的 “自定义” )

    • 项目中引入 Redis 依赖 后,Spring Boot 提供的 RedisAutoConfiguration 自动配置生效 ( Redis自动配置类 生效)。

      打开RedisAutoConfiguration 类查看内部源码 中关于 RedisTemplate定义方式核心代码如下所示 :

      public class RedisAutoConfiguration {
      
        @Bean
        @ConditionalOnMissingBean( name = {"redisTemplate"} )
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
              RedisTemplate<Object, Object> template = new RedisTemplate();
              template.setConnectionFactory(redisConnectionFactory);
              return template;
          }
        .....
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      从上述 RedisAutoConfiguration 核心源码中可以看出,在 Redis 自动配置类 中,通过 RedisConnectionFactory ( Redis连接工厂对象 ) 初始化 了一个 RedisTemplate 对象 ( Redis模板对象 )。

      RedisTemplate上方添加了 @ConditionalOnMissingBean 注解( 顾名思义,当某个 Bean 不存在时生效 ),用来 表明如果 开发者自定义了一个名为 redisTemplateBean,则 RedisTemplate使用自定义Bean

    • 如果 想要使用自定义序列化方式的 RedisTemplate对象 进行数据缓存操作,可以参考上述核心创建一个名为 redisTemplate 对象Bean 组件,并 在该组件中 设置 对应的序列化方式 ( JSON序列化方式 ) 即可。

      配置类代码例子如 :

      RedisConfig.java

      import com.fasterxml.jackson.annotation.JsonAutoDetect;
      import com.fasterxml.jackson.annotation.PropertyAccessor;
      import com.fasterxml.jackson.databind.ObjectMapper;
      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;
      
        @Configuration //标记该类为"配置类",定义一个配置类
        public class RedisConfig { //关于RedisTemplate对象的配置类
              @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { //参数为: Redis连接工厂对象
            //创建RedisTemplate对象
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate();
            //设置Redis连接工厂对象
            redisTemplate.setConnectionFactory(redisConnectionFactory );
                  //设置解决缓存异常问题
            ObjectMapper objectMapper  = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      
            /*
              使用"JSON格式序列化机制" 对缓存数据key和value进行转换
             */
            Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(objectMapper,Object.class);
            //设置RedisTemplate对象的"序列化机制" 为 "JSON序列化机制"
            redisTemplate.setDefaultSerializer(jsonRedisSerializer);
      
            return redisTemplate;
          }
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32

      在上面的代码中,使用 自定义Jackson2JsonRedisSerializer数据序列化方式自定义一个 RedisTemplate,在定制序列化方式中,定义一个ObjectMapper 用于进行数据转换设置


      基于 “API” ( RedisTemplate类 ) 的 “Redis缓存管理” ,在 左边的项目代码基础上添加 RedisConfig.java 配置类启动该项目访问ulr,可以看到 Redis数据库中的数据为 JSON格式 ( 如下图所示 ),便于查看和管理,表明其实 序列化方式为 : JSON序列化方式

      在这里插入图片描述

  • 相关阅读:
    Python基础-6-字典
    Java中set集合简介说明
    java多线程使用详解与案例,超详细
    基于51单片机的双机串口通信proteus仿真原理图PCB
    CF1168C And Reachability
    SQL语法常用总结
    elasticsearch DSL部分 源码解析
    【Java】 java | 正则 | 正则表达式 | 强密码
    Android 13 定制化开发--开启相机或麦克风时,去掉状态栏上的绿色图标
    Mybatis-plus 怎么使用拦截器拿到SQL,并解析
  • 原文地址:https://blog.csdn.net/m0_70720417/article/details/138202309