首页 > 其他分享 >SpringBoot 项目中配置多个 Jackson 的 ObjectMapper ,以及配置遇到的坑

SpringBoot 项目中配置多个 Jackson 的 ObjectMapper ,以及配置遇到的坑

时间:2023-01-13 11:57:06浏览次数:60  
标签:Jackson SpringBoot 配置文件 配置 bean ConditionalOnMissingBean ObjectMapper 注入

目录

问题说明

我们都知道,SpringBoot 项目中,如果引入了 Jackson 的包,哪怕不配置,SpringBoot 也会帮我们配置(JacksonAutoConfiguration)。

由于我的项目中需要使用多个不同的配置参数的 ObjectMapper,我同事直接配置了两个@Bean,并且其中一个使用@ConditionalOnMissingBean 和@Primary 标注,但是奇怪的是,居然两个 Bean 都注入成功了,瞬间对这块逻辑产生了怀疑,本着探索的精神,进行分析!

  • 问题 1:自定义配置文件中第一个注入的 Bean 和 JacksonAutoConfiguration 一模一样,为啥还需要重新写一遍,是否把第一个删除了?
  • 问题 2:@ConditionalOnMissingBean 不应该是缺少该对象实例才会注入,否则不注入嘛?
@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        return builder.createXmlMapper(false).build();
    }

    @Bean("snakeCaseObjectMapper")
    public ObjectMapper snakeCaseObjectMapper() {
        ObjectMapper result = new ObjectMapper();
        result.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        result.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // java8日期日期处理
        JacksonUtil.setDateTimeSerializer(result);

        return result;
    }
}

原因排查分析

通过修改代码进行测试

  1. 将配置文件第一个删除掉,测试发现,只注入了一个名称为 snakeCaseObjectMapper 的 bean;
  2. 注释掉注解 @ConditionalOnMissingBean,测试发现,两个 bean 都注入成功;
  3. 将 @ConditionalOnMissingBean 放在第二个 bean 上,测试发现,只注入了第一个 bean;
  4. 将配置的两个 bean 调换上下顺序,测试发现,只注入了第一个 bean;
  5. 将配置文件第一个删除掉,并将 @ConditionalOnMissingBean 放在第二个 bean 上,测试发现,只注入了第二个 bean。

问题答案:

第一个问题,虽然第一个 bean 和自动配置中的一样,但是由于自定义配置和自动配置文件加载顺序的原因,就会产生不同的结果,所以是不能删除的。

第二个问题,@ConditionalOnMissingBean 其实可以省略,如果调用两个 bean 的上下顺序,这个就注入不成功,因为同一个配置文件中,如果没有依赖关系,则按照上下顺序进行加载的。

结论总结

  • 同一个配置文件中,如果多个 bean 没有依赖关系,则按照上下顺序进行加载。

  • Spring Boot 的自动配置均是通过 spring.factories 来指定的,它的优先级最低(执行时机是最晚的);通过扫描进来的(也就是项目组自定义配置类)优先级是最高的。

  • 自动配置顺序相关的三大注解 @AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder 只能作用于自动配置类,不能作用于被启动类扫描的配置类中。

Jackson 自动装配分析

  1. 在这个 JacksonAutoConfiguration 类里面会生成一个 Primary 的 ObjectMapper 的 bean,注入 ObjectMapper 的 bean 时,依赖了 Jackson2ObjectMapperBuilder 的 bean;

  2. 找到注入 Jackson2ObjectMapperBuilder 的 bean,发现其依赖 List,具体操作就是把容器里面的所有的 Jackson2ObjectMapperBuilderCustomizer 拿出来,对 Jackson2ObjectMapperBuilder 进行设置;Jackson2ObjectMapperBuilderCustomizer 接口只有一个方法,其实就是 Jackson2ObjectMapperBuilder 提供的回调钩子方法;

  3. 因此,如果要对 ObjectMapper 做自定义配置化操作,要么实现 Jackson2ObjectMapperBuilderCustomizer 接口并注入这个实现的 bean,要么直接使用 Jackson2ObjectMapperBuilder 进行配置。

参考链接:ConditionalOnMissingBean失效问题追踪

标签:Jackson,SpringBoot,配置文件,配置,bean,ConditionalOnMissingBean,ObjectMapper,注入
From: https://www.cnblogs.com/dxiaodang/p/17049168.html

相关文章

  • springboot集成swagger3
     1pom.xml增加  <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependen......
  • 【Mongodb结合springboot 01】
    一、简介1、什么是MongoDBc++语言编写的,是一个基于分布式文件存储的开源数据库系统;为web应用提供可扩展的高性能数据存储解决方案;MongoDB将数据存储为一个文档,数据结构......
  • 零基础学习SpringBoot3笔记01_2023-01-13
    零基础学习SpringBoot3笔记01_2023-01-132023-01-131.环境1.1.软件环境安装JDK17并配置环境变量,略安装MySQL5.5并配置环境变量,略安装MySQL客户端工具HeidiSQL,略......
  • SpringBoot-JSR303数据校验
    什么是JSR303?Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;@Componen......
  • SpringBoot整合MinIO实现分布式文件服务
    注:本文转自:https://mp.weixin.qq.com/s/0vffJxhu_cBDokQbhhazhA什么是MinIO?Minio是个基于Golang编写的开源对象存储套件,基于ApacheLicensev2.0开源协议,虽然轻量,却拥......
  • 230112_50_SpringBoot入门
    springboot主启动类程序分析pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org......
  • SpringBoot-中英文页面切换(国际化)
    目录1.设置项目编码UTF82.在resources目录下新建i18n文件夹及语言配置文件3.指出国际化相关文件的位置4.展示页面5.使用按钮切换中英文页面5.1新建html页面5.2实现L......
  • SpringBoot简单整合JPA
    SpringBoot简单整合JPAhttps://blog.csdn.net/qq_41378597/article/details/103444889最近帮朋友写个小项目,用惯了Mybatis,有机会想用下SpringBoot整合JPA,发现使用JPA......
  • Springboot简单整合JPA示例
    Springboot整合JPAhttps://blog.csdn.net/wdy00000/article/details/123588201文章目录JPA技术常用注解Springboot整合JPA1.引入JPA依赖2.配置3.启动类4.实体类5.......
  • springboot 自动配置 自动监控demo
    1、注解定义@Target({java.lang.annotation.ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceUmp{publicabstractSt......