更新到 Spring Boot 2 后 Jackson 模块未注册
Posted
技术标签:
【中文标题】更新到 Spring Boot 2 后 Jackson 模块未注册【英文标题】:Jackson module not registered after update to Spring Boot 2 【发布时间】:2020-08-22 16:50:31 【问题描述】:我正在从 Spring Boot 1.5.21 升级到 2.2.5。
我需要使用MonetaryModule
来反序列化rest 调用,这取决于Spring 的ObjectMapper
。
我在某个@Configuration
类中为这个模块定义了这样一个bean(MonetaryModule
正在扩展Module
):
@Bean
public MonetaryModule monetaryModule()
return new MonetaryModule();
我可以在/beans
端点中看到它已创建。但是,它实际上并未加载到ObjectMapper
。在对 Spring 的代码进行了大量的调试和挖掘之后,我得出的结论是 JacksonAutoConfiguration
有问题。它有一个名为JacksonObjectMapperBuilderConfiguration
的内部静态类,其中有一个bean
创建Jackson2ObjectMapperBuilder
。在创建过程中,调用customize()
最终会得到以下代码:
private void configureModules(Jackson2ObjectMapperBuilder builder)
Collection<Module> moduleBeans = getBeans(this.applicationContext, Module.class);
builder.modulesToInstall(moduleBeans.toArray(new Module[0]));
这段代码似乎负责将模块加载到ObjectMapper
,问题是这个Jackson2ObjectMapperBuilder
实际上并没有创建。它出现在/beans
端点中,但事实上,当我在那里断点时,我没有到达断点。这就解释了为什么模块没有加载到ObjectMapper
。
问题是,为什么这段代码没有被调用?为什么/bean
表明该bean 确实存在?
编辑-添加条件评估报告:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration matched:
- @ConditionalOnClass found required class 'org.aspectj.weaver.Advice' (OnClassCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration.CglibAutoProxyConfiguration matched:
- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)
ConfigServiceBootstrapConfiguration#configServicePropertySource matched:
- @ConditionalOnProperty (spring.cloud.config.enabled) matched (OnPropertyCondition)
- @ConditionalOnMissingBean (types: org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; SearchStrategy: all) did not find any beans (OnBeanCondition)
ConfigServiceBootstrapConfiguration.RetryConfiguration matched:
- @ConditionalOnClass found required classes 'org.springframework.retry.annotation.Retryable', 'org.aspectj.lang.annotation.Aspect', 'org.springframework.boot.autoconfigure.aop.AopAutoConfiguration' (OnClassCondition)
- @ConditionalOnProperty (spring.cloud.config.fail-fast) matched (OnPropertyCondition)
ConfigServiceBootstrapConfiguration.RetryConfiguration#configServerRetryInterceptor matched:
- @ConditionalOnMissingBean (names: configServerRetryInterceptor; SearchStrategy: all) did not find any beans (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration matched:
- @ConditionalOnBean (types: org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; SearchStrategy: all) found bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor' (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration#configurationPropertiesBeans matched:
- @ConditionalOnMissingBean (types: org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; SearchStrategy: current) did not find any beans (OnBeanCondition)
ConfigurationPropertiesRebinderAutoConfiguration#configurationPropertiesRebinder matched:
- @ConditionalOnMissingBean (types: org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; SearchStrategy: current) did not find any beans (OnBeanCondition)
EncryptionBootstrapConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.security.crypto.encrypt.TextEncryptor' (OnClassCondition)
PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer matched:
- @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
AopAutoConfiguration.AspectJAutoProxyingConfiguration.JdkDynamicAutoProxyConfiguration:
Did not match:
- @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property 'proxy-target-class' (OnPropertyCondition)
AopAutoConfiguration.ClassProxyingConfiguration:
Did not match:
- @ConditionalOnMissingClass found unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
DiscoveryClientConfigServiceBootstrapConfiguration:
Did not match:
- @ConditionalOnProperty (spring.cloud.config.discovery.enabled) did not find property 'spring.cloud.config.discovery.enabled' (OnPropertyCondition)
EncryptionBootstrapConfiguration.RsaEncryptionConfiguration:
Did not match:
- Keystore nor key found in Environment (EncryptionBootstrapConfiguration.KeyCondition)
Matched:
- @ConditionalOnClass found required class 'org.springframework.security.rsa.crypto.RsaSecretEncryptor' (OnClassCondition)
EncryptionBootstrapConfiguration.VanillaEncryptionConfiguration:
Did not match:
- @ConditionalOnMissingClass found unwanted class 'org.springframework.security.rsa.crypto.RsaSecretEncryptor' (OnClassCondition)
Exclusions:
-----------
None
Unconditional classes:
----------------------
None
另外,附上/conditions
和/beans
端点输出的输出(太大,无法粘贴到帖子本身)
endpoints output
【问题讨论】:
任何具有自己的自动配置(...并创建 Jackson2ObjectMapperBuilder)的库? 我不知道... 你试过调试Jackson2ObjectMapperBuilder的默认构造函数吗? (至少在 Intellij Idea 中应该是可能的,根据一些快速的谷歌搜索,Eclipse 似乎也知道这一点。) Jackson2ObjectMapperBuilder 的 CTOR 在我调试的 MappingJackson2CborHttpMessageConverter 中使用(在我的场景中)。它不包含所需的模块。 您可以尝试在此处提供更多信息(您的主应用程序类、应用程序属性、WebMvcConfigurer 自定义类、自动配置报告)或尝试在您可以共享的小项目中重现问题。如果没有这些,恐怕我们无法帮助您。 【参考方案1】:您的病情评估报告显示如下:
"JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper":
"notMatched": [
"condition": "OnBeanCondition",
"message": "@ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found beans of type 'com.fasterxml.jackson.databind.ObjectMapper' jacksonBuilder"
],
"matched": []
,
这意味着 Spring Boot 自动配置条件正在退出,因为您的应用程序已经就此事提供了意见:已经有一个名为 jacksonBuilder
的 ObjectMapper
bean;它由应用程序或您正在使用的库中的某个配置类提供。
在这种情况下,这来自一个配置类,正如 bean 端点所指出的那样:
"jacksonBuilder":
"aliases": [],
"scope": "singleton",
"type": "com.fasterxml.jackson.databind.ObjectMapper",
"resource": "class path resource [com/behalf/core/authorization_domain/config/AuthorizationDomainConfiguration.class]",
"dependencies": []
,
您应该在这里与AuthorizationDomainConfiguration
的维护者取得联系,并让他们知道他们应该避免覆盖应用程序对 JSON(反)序列化的意见。
【讨论】:
就是这样!非常感谢!以上是关于更新到 Spring Boot 2 后 Jackson 模块未注册的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot cloud vault 更新到 3.0.3 版本后不再加载属性
更新到 Spring Boot 1.5.8 和 Finchley/Edgware Spring Cloud 后 Feign Exception 403
未使用 Spring Boot 2.3 调用 RestControllerAdvice
Spring Boot - 从 2.2.5 升级到 2.3.0 后验证停止工作
独立资源服务器(Spring Boot 2 + OAuth + JWT)在 Spring-boot 从 1.2.x 升级到 2.x 后给出 UsernameNotFoundException