SpringBoot调试日志中Bean可见性区分及非公开Bean注入疑问
关于Spring Boot中非公开@Bean的全局注入与条件匹配问题
问题背景
自定义自动配置启动失败,原因是@ConditionalOnBean(ObjectMapper.class)条件检查不通过,但通过设置debug=true启动日志,确认com.fasterxml.jackson.databind.ObjectMapper Bean已被创建。
启动日志排查结果
启动日志明确显示该Bean创建成功:
JacksonAutoConfiguration matched: - @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper' (OnClassCondition) JacksonAutoConfiguration.Jackson2ObjectMapperBuilderCustomizerConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder' (OnClassCondition) JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder' (OnClassCondition) JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder matched: - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition) JacksonAutoConfiguration.JacksonObjectMapperConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder' (OnClassCondition) /////////////////////// IT IS HERE! JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper matched: - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)
代码实现细节
查看JacksonAutoConfiguration源码后发现,该Bean对应的内部配置类和Bean方法均为非公开访问权限:
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(ObjectMapper.class) public class JacksonAutoConfiguration { ...... @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Jackson2ObjectMapperBuilder.class) static class JacksonObjectMapperConfiguration { @Bean @Primary @ConditionalOnMissingBean ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { return builder.createXmlMapper(false).build(); } } }
核心疑问
- 这类非公开的
@Bean是否可以全局注入? - 若不可,如何在调试日志中区分这类“隐藏”Bean与公开Bean?
- 为什么自定义自动配置的
@ConditionalOnBean(ObjectMapper.class)会检查失败?
解答
1. 非公开@Bean的全局可用性
Spring容器不关心@Bean方法或其所在配置类的访问修饰符,只要配置类被Spring扫描加载,内部@Bean方法定义的Bean就会被注册到容器中,完全可以全局注入使用。
2. 调试日志中区分公开/非公开Bean
默认debug=true日志不会直接标记Bean的访问权限,但可以通过两种方式区分:
- 查看日志中Bean的归属类:如果Bean属于配置类的内部静态类(如
JacksonAutoConfiguration.JacksonObjectMapperConfiguration),且该内部类是非公开的,对应的Bean方法大概率也是非公开的。 - 开启更详细日志:将
org.springframework.beans.factory.support日志级别设为DEBUG,可查看Bean定义来源方法的访问修饰符信息。
3. @ConditionalOnBean检查失败的原因
核心问题是配置类加载顺序:
自定义自动配置类的加载时机早于JacksonAutoConfiguration,此时ObjectMapper Bean尚未创建,导致@ConditionalOnBean条件不满足。Spring Boot自动配置类的加载顺序由@AutoConfigureBefore/@AutoConfigureAfter/@AutoConfigureOrder控制,未指定这些注解的自定义配置可能先于Jackson自动配置加载。
解决方法:
- 在自定义自动配置类上添加
@AutoConfigureAfter(JacksonAutoConfiguration.class),确保在ObjectMapperBean创建完成后再加载你的配置。 - 若只需确保
ObjectMapper类存在而非容器管理的Bean,可替换为@ConditionalOnClass(ObjectMapper.class)。
内容的提问来源于stack exchange,提问作者Antoniossss
相关产品推荐
相关产品推荐

