SpringBoot怎么自定义Redis实现缓存序列化


1、自定义RedisTemplate

1.1、Redis API默认序列化机制

基于api的redis缓存实现是使用redistemplate模板进行数据缓存操作的,这里打开redistemplate类,查看该类的源码信息

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
    // 声明了key、value的各种序列化方式,初始值为空
    @Nullable
    private RedisSerializer keySerializer = null;
    @Nullable
    private RedisSerializer valueSerializer = null;
    @Nullable
    private RedisSerializer hashKeySerializer = null;
    @Nullable
    private RedisSerializer hashValueSerializer = null;
...
    // 进行默认序列化方式设置,设置为JDK序列化方式
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        boolean defaultUsed = false;
        if (this.defaultSerializer == null) {
            this.defaultSerializer = new JdkSerializationRedisSerializer(
                    this.classLoader != null ?
                            this.classLoader : this.getClass().getClassLoader());
        }
        ...
    }
        ...
}

从上述RedisTemplate核心源码可以看出,在RedisTemplate内部声明了缓存数据key、value的各种序列化方式,且初始值都为空;在afterPropertiesSet()方法中,判断如果默认序列化参数defaultSerializer为空,将数据的默认序列化方式设置为JdkSerializationRedisSerializer

根据上述源码信息的分析,可以得到以下两个重要的结论:

(1)使用RedisTemplate进行Redis数据缓存操作时,内部默认使用的是JdkSerializationRedisSerializer序列化方式,所以进行数据缓存的实体类必须实现JDK自带的序列化接口(例如Serializable);

(2)使用RedisTemplate进行Redis数据缓存操作时,如果自定义了缓存序列化方式defaultSerializer,那么将使用自定义的序列化方式。

另外,在RedisTemplate类源码中,看到的缓存数据key、value的各种序列化类型都是RedisSerializer。进入RedisSerializer源码查看RedisSerializer支持的序列化方式(进入该类后,使用Ctrl+Alt+左键单击类名查看)

SpringBoot怎么自定义Redis实现缓存序列化

可以看出,RedisSerializer是一个Redis序列化接口,默认有6个实现类,这6个实现类代表了6种不同的数据序列化方式。其中,JdkSerializationRedisSerializer是JDK自带的,也是RedisTemplate内部默认使用的数据序列化方式,开发者可以根据需要选择其他支持的序列化方式(例如JSON方式)

1.2、自定义RedisTemplate序列化机制

在项目中引入Redis依赖后,Spring Boot提供的RedisAutoConfiguration自动配置会生效。打开RedisAutoConfiguration类,查看内部源码中关于RedisTemplate的定义方式

public class RedisAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(
            name = {"redisTemplate"}
    )
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
...
}

从上述RedisAutoConfiguration核心源码中可以看出,在Redis自动配置类中,通过Redis连接工厂RedisConnectionFactory初始化了一个RedisTemplate;该类上方添加了@ConditionalOnMissingBean注解(顾名思义,当某个Bean不存在时生效),用来表明如果开发者自定义了一个名为redisTemplate的Bean,则该默认初始化的RedisTemplate不会生效。

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

接下来,在项目中创建名为com.lagou.config的包,在该包下创建一个Redis自定义配置类RedisConfig,并按照上述思路自定义名为redisTemplate的Bean组件

@Configuration
public class RedisConfig {
    // 自定义RedisTemplate
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 创建一个JSON格式序列化对象,对缓存数据的key和value进行转换
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 设置RedisTemplate模板api序列化方式为json
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        return template;
    }
}

通过@Configuration注解定义了一个RedisConfig配置类,并使用@Bean注解注入了一个默认名称为方法名的redisTemplate组件(注意,该Bean组件名称必须是redisTemplate)。在定义的Bean组件中,自定义了一个RedisTemplate,使用自定义的Jackson2JsonRedisSerializer数据序列化方式;在定制序列化方式中,定义了一个ObjectMapper用于进行数据转换设置

1.3、效果测试

SpringBoot怎么自定义Redis实现缓存序列化

可以看出,执行findById()方法正确查询出用户评论信息Comment,重复进行同样的查询操作,数据库只执行了一次SQL语句,这说明定制的Redis缓存生效。

Mootion Mootion

Mootion是一个革命性的3D动画创作平台,利用AI技术来简化和加速3D动画的制作过程。

Mootion 232 查看详情 Mootion

使用Redis客户端可视化管理工具Redis Desktop Manager查看缓存数据 :

SpringBoot怎么自定义Redis实现缓存序列化

执行findById()方法查询出用户评论信息Comment正确存储到了Redis缓存库中,且缓存到Redis服务的数据已经使用了JSON格式存储展示,查看和管理也非常方便,说明自定义的Redis API模板工具RedisTemplate生效

2、自定义RedisCacheManager

刚刚针对基于 API方式的RedisTemplate进行了自定义序列化方式的改进,从而实现了JSON序列化方式缓存数据,但是这种自定义的RedisTemplate对于基于注解的Redis缓存来说,是没有作用的。

接下来,针对基于注解的Redis缓存机制和自定义序列化方式进行讲解

2.1、Redis注解默认序列化机制

打开Spring Boot整合Redis组件提供的缓存自动配置类RedisCacheConfiguration(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 = this.cacheProperties.getCacheNames();
        if (!cacheNames.isEmpty()) {
            builder.initialCacheNames(new LinkedHashSet(cacheNames));
        }
        return (RedisCacheManager) this.customizerInvoker.customize(builder.build());
    }
    private org.springframework.data.redis.cache.RedisCacheConfiguration
    determineConfiguration(ClassLoader classLoader) {
        if (this.redisCacheConfiguration != null) {
            return this.redisCacheConfiguration;
        } else {
            Redis redisProperties = this.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;
        }
    }
}

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

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

在Spring Boot 2.X版本中,RedisCacheManager是独立构建的。因此,在SpringBoot 2.X版本中,对RedisTemplate进行自定义序列化机制构建后,仍然无法对RedisCacheManager内部默认序列化机制进行覆盖(这也就解释了基 于注解的Redis缓存实现仍然会使用JDK默认序列化机制的原因),想要基于注解的Redis缓存实现也使用自定义序列化机制,需要自定义RedisCacheManager

2.2、自定义RedisCacheManager

在项目的Redis配置类RedisConfig中,按照上一步分析的定制方法自定义名为cacheManager的Bean组件

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换
        RedisSerializer<String> strSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jacksonSerial = new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // 上面注释过时代码的替代方法
        jacksonSerial.setObjectMapper(om);
        // 定制缓存数据序列化方式及时效
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1)) // 设置缓存数据的时效(设置为了1天)
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(strSerializer)) // 对当前对象的key使用strSerializer这个序列化对象,进行转换
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(jacksonSerial)) // 对value使用jacksonSerial这个序列化对象,进行转换
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager
                .builder(redisConnectionFactory).cacheDefaults(config).build();
        return cacheManager;
    }

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

完成基于注解的Redis缓存管理器RedisCacheManager定制后,可以对该缓存管理器的效果进行测试(使用自定义序列化机制的RedisCacheManager测试时,实体类可以不用实现序列化接口)

以上就是SpringBoot怎么自定义Redis实现缓存序列化的详细内容,更多请关注其它相关文章!


# SpringBoot  # 推荐网络营销推广的书目  # 临沧网络推广网络营销  # Na2SeO3溶液  # 沧州网站建设产品介绍  # 推广营销流程及方案  # 自带  # 并在  # 为空  # 设置为  # 是一个  # 管理器  # 创建一个  # 可以看出  # 自定义  # 序列化  # redis  # 李东健电影网站建设  # 广西阳朔县免费网站推广  # 保定市手机排名seo  # seo外包-认准优加  # 南安网站建设设计公司 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 斯宾塞称XGP云游戏“蒸蒸日上”:正在构建一个游戏从未如此唾手可得的未来  如何在Podman容器中运行Composer_Docker替代品Podman的PHP与Composer容器化实践  如何外贸网站设计-能留住客户提升用户体验!  C++如何使用CMake构建项目_C++ CMakeLists.txt编写入门教程  C++怎么解决数值计算中的精度问题_C++浮点数误差与数值稳定性分析  t3出行如何使用微信支付  《合金装备4》有望推出重制版!制作人发话了  《全民k歌》音乐怎么下载到本地2025  菜鸟裹裹怎样获得取件码_菜鸟裹裹获得取件码步骤  《雷电模拟器》自动点击设置方法  《雷电模拟器》截图方法介绍  空腹吃苹果好吗 苹果空腹摄入指南  sublime如何处理超大文件不卡顿 _sublime打开大日志文件技巧  服装短视频如何起号推广?服装短视频起号推广有什么要求?  iPhone17Pro如何连接蓝牙耳机_iPhone17Pro蓝牙设备配对与连接方法介绍  如何查找哪个composer包引入了特定的依赖?  KFC邀请码怎么使用领额外优惠_KFC邀请码输入方式与额外优惠代码获取方法  mysql中如何配置字符集和排序规则_mysql字符集排序配置  mysql如何配置从库只读_mysql从库只读设置方法  Sublime怎么快速复制文件路径_Sublime右键菜单增强技巧  《新三国志曹操传》游历事件袁尚突围攻略  c++如何掌握指针的核心用法_c++指针入门到精通指南  从J*a应用程序中导出MySQL表数据的技术指南  Lar*el怎么实现全文搜索_Lar*el Scout集成Algolia教程  search中maxlength属性用法解析  在Spring Boot Thymeleaf中利用布尔属性实现容器的条件显示  掌握Go App Engine项目结构与GOPATH:包管理与导入实践  192.168.1.1路由器后台入口 192.168.1.1默认登录入口  申通快递查询 申通物流快递单实时查询入口  快递查询,一键速查  在VS Code中进行数据科学和机器学习开发  Golang如何使用log记录日志信息_Golang log日志记录方法总结  支付宝登录刷脸不是本人如何解决  使用CSS :has() 选择器实现父元素样式控制:从子元素反向应用样式  酷狗音乐多音轨设置教程  《oppo商城》维修服务位置  CDR如何复制交互式填充色  C++ optional用法详解_C++17处理可能为空的返回值  实时数据流中高效查找最小值与最大值  163邮箱登录入口官网 163.com邮箱登录入口  iPhone 15 Pro如何查看存储空间占用_iPhone 15 Pro存储空间查看教程  美发店速赢秘籍  C++中的explicit关键字有什么作用_C++类型转换控制与explicit使用  德邦快递收费标准详解  多多买菜门店端app订单查看方法  小红书网页版怎么进 小红书网页版通用入口  12306不能订票的时间段是固定的吗? | 节假日购票时间有无变化  咸鱼怎么设置仅粉丝可见的动态_咸鱼动态粉丝可见设置方法  京东快递包裹信息查询入口 京东快递官方查询平台入口  OpenWeatherMap API:通过城市名称获取天气预报数据指南 

 2023-06-03

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.