为何通过new创建的Spring Bean仍能实现属性注入?
问题:通过new实例化的@ConfigurationProperties类为何能完成属性注入?
我遇到一个疑惑:有一个@Bean方法直接返回通过new实例化的对象,但该类带有@ConfigurationProperties注解,运行时居然能正常实现属性注入。
相关的@Bean方法代码如下:
@Bean @ConditionalOnMissingBean public ConfigClientProperties configClientProperties(Environment environment, ApplicationContext context) { if (context.getParent() != null && BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getParent(), ConfigClientProperties.class).length > 0) { return BeanFactoryUtils.beanOfTypeIncludingAncestors(context.getParent(), ConfigClientProperties.class); } // this looks like a standard constructor call // why would Spring "know" to inject fields ConfigClientProperties client = new ConfigClientProperties(environment); return client; }
按常规理解,通过new创建的对象会绕过Spring的属性注入,但这个ConfigClientProperties类(它是spring-cloud-config-client中封装spring.cloud.config*系列配置的对象,用于HTTP请求)的实例,虽由new创建,运行时所有字段仍能从配置中正确填充。
简言之:Spring容器是如何识别通过new创建的对象,匹配其@ConfigurationProperties注解并完成属性注入,而非让对象处于未注入状态?
原理解析
- @ConfigurationProperties的专属后置处理器:Spring为标注了
@ConfigurationProperties的Bean提供了专门的处理机制——ConfigurationPropertiesBindingPostProcessor。这个后置处理器是Spring容器的内置Bean,会在Bean生命周期的初始化阶段介入。 - Bean注册后的后置处理流程:当@Bean方法返回new出来的对象后,该对象会被Spring容器注册为一个管理Bean。在Bean完成实例化和依赖注入后,后置处理器会扫描到这个带有
@ConfigurationProperties注解的Bean,根据注解中指定的配置前缀,从Environment中读取对应配置项,通过属性绑定机制将值填充到Bean的字段中。 - 核心:new对象成为Spring Bean才是关键:这里的误区是以为Spring直接对new出来的对象做了注入,实际上是new出来的对象通过@Bean方法被纳入Spring容器管理后,才触发了后续的配置属性绑定流程。如果只是单纯用new创建对象而不交给Spring容器管理,那确实不会有属性注入的效果。
内容的提问来源于stack exchange,提问作者Anthony Alba
相关产品推荐
相关产品推荐

