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

科技资讯 投稿 5600 0 评论

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

问题说明

由于我的项目中需要使用多个不同的配置参数的 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;
    }
}

原因排查分析

通过修改代码进行测试

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

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

结论总结

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

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

Jackson 自动装配分析

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

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

编程笔记 » SpringBoot 项目中配置多个 Jackson 的 ObjectMapper ,以及配置遇到的坑

赞同 (31) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽