如何基于Spring Boot自动配置定义自定义Jackson ObjectMapper Bean
我完全懂你的困扰——想基于Spring Boot自动配置好的ObjectMapper做一个自定义版本,只给应用的部分模块用,还担心升级Spring Boot的时候依赖的API变来变去,怕踩坑对吧?毕竟直接用自动配置好的ObjectMapper来copy,肯定是最贴合Spring Boot默认行为、升级也最省心的方式,但偏偏被@ConditionalOnMissingBean的条件卡了壳。
先给你说最推荐、最稳的方案:直接依赖Jackson2ObjectMapperBuilder。
你可能担心这个Builder的API不稳定,但其实大可放心——Jackson2ObjectMapperBuilder是Spring Boot官方用来构建ObjectMapper的核心类,团队在版本迭代时会极力保证它的API兼容性,毕竟这是官方推荐的Jackson配置入口。用它的话,你可以先构建出和自动配置完全一致的ObjectMapper,再在此基础上做自定义修改,完美复用Spring Boot自动配置的所有设置(比如从配置文件读的规则、自动注册的模块等)。代码示例如下:
@Configuration class WebConfig { @Bean fun customObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper { // 先构建和自动配置一模一样的基础ObjectMapper val baseMapper = builder.createXmlMapper(false).build() // 复制后添加你的自定义配置 return baseMapper.copy() .setSerializationInclusion(JsonInclude.Include.NON_NULL) .registerModule(JavaTimeModule()) // 这里加你需要的其他自定义设置 } }
如果你实在想绕开Builder,坚持要直接依赖自动配置的ObjectMapper,也有个小技巧,不过我不太推荐,因为操作起来有点绕,而且容易出问题:
你可以让配置类实现ApplicationContextAware,在Spring容器初始化完成后,手动获取自动配置的ObjectMapper,再创建自定义的Bean。同时要加上@AutoConfigureAfter注解,确保你的配置类在Jackson自动配置之后执行,避免找不到Bean的情况。代码示例:
@Configuration @AutoConfigureAfter(JacksonAutoConfiguration::class) class WebConfig : ApplicationContextAware { private lateinit var applicationContext: ApplicationContext override fun setApplicationContext(applicationContext: ApplicationContext) { this.applicationContext = applicationContext } @Bean fun customObjectMapper(): ObjectMapper { // 从容器中拿到自动配置好的ObjectMapper val autoConfiguredMapper = applicationContext.getBean(ObjectMapper::class.java) // 复制并做自定义修改 return autoConfiguredMapper.copy() // 你的自定义配置 } }
不过说实话,这个方法不如第一个方案简洁直观,而且依赖了JacksonAutoConfiguration的类名,虽然这个类名也比较稳定,但还是不如直接用Builder来得省心。
总结一下,最稳妥、最适配Spring Boot升级节奏的方式还是第一个方案,直接用Jackson2ObjectMapperBuilder来构建基础Mapper再自定义。
内容来源于stack exchange

