关于 @EnableConfigurationProperties 注解
先說(shuō)作用:
@EnableConfigurationProperties注解的作用是:使使用 @ConfigurationProperties 注解的類生效。
說(shuō)明:
用springboot開(kāi)發(fā)的過(guò)程中,我們會(huì)用到@ConfigurationProperties注解,主要是用來(lái)把properties或者yml配置文件轉(zhuǎn)化為bean來(lái)使用的,而@EnableConfigurationProperties注解的作用是@ConfigurationProperties注解生效。
如果只配置@ConfigurationProperties注解,在IOC容器中是獲取不到properties配置文件轉(zhuǎn)化的bean的,當(dāng)然在@ConfigurationProperties加入注解的類上加@Component也可以使交于springboot管理。
說(shuō)白了 @EnableConfigurationProperties 相當(dāng)于把使用 @ConfigurationProperties 的類進(jìn)行了一次注入。
?
測(cè)試:
@ConfigurationProperties?與?@EnableConfigurationProperties?的關(guān)系。
@EnableConfigurationProperties?文檔中解釋:
當(dāng)@EnableConfigurationProperties注解應(yīng)用到你的@Configuration時(shí), 任何被@ConfigurationProperties注解的beans將自動(dòng)被Environment屬性配置。 這種風(fēng)格的配置特別適合與SpringApplication的外部YAML配置進(jìn)行配合使用。
測(cè)試發(fā)現(xiàn):
1.使用?@EnableConfigurationProperties?進(jìn)行注冊(cè)
自動(dòng)配置設(shè)置
service.properties.name=my-test-name service.properties.ip=192.168.1.1 service.user=kayle service.port=8080一切正常,但是 HelloServiceAutoConfiguration 頭部不使用?@EnableConfigurationProperties,測(cè)訪問(wèn)報(bào)錯(cuò)。
2.不使用?@EnableConfigurationProperties?進(jìn)行注冊(cè),使用?@Component?注冊(cè)
@ConfigurationProperties(prefix = "service.properties") @Component public class HelloServiceProperties {private static final String SERVICE_NAME = "test-service";private String msg = SERVICE_NAME;public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}Controller 不變,一切正常,如果注釋掉 @Component 測(cè)啟動(dòng)報(bào)錯(cuò)。
由此證明,兩種方式都是將被 @ConfigurationProperties 修飾的類,加載到 Spring Env 中。
測(cè)試環(huán)境:SpringBoot1.5
?
@EnableConfigurationProperties是怎么加載的
通過(guò)查看@EnableConfigurationProperties的注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EnableConfigurationPropertiesImportSelector.class) public @interface EnableConfigurationProperties {/*** Convenient way to quickly register {@link ConfigurationProperties} annotated beans* with Spring. Standard Spring Beans will also be scanned regardless of this value.* @return {@link ConfigurationProperties} annotated beans to register*/Class<?>[] value() default {};}通過(guò)分析自動(dòng)配置可以知道,肯定是這個(gè)類EnableConfigurationPropertiesImportSelector起的作用;@Import的作用就是把這個(gè)ImportSelector的selectImprts()方法返回的類名的類加載到IOC容器中。
/*** 將ConfigurationPropertiesBeanRegistrar、ConfigurationPropertiesBindingPostProcessorRegistrar這兩個(gè)類注冊(cè)到容器中。*/ @Override public String[] selectImports(AnnotationMetadata metadata) {MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(EnableConfigurationProperties.class.getName(), false);Object[] type = attributes == null ? null: (Object[]) attributes.getFirst("value");if (type == null || type.length == 0) {return new String[] {ConfigurationPropertiesBindingPostProcessorRegistrar.class.getName() };}return new String[] { ConfigurationPropertiesBeanRegistrar.class.getName(),ConfigurationPropertiesBindingPostProcessorRegistrar.class.getName() }; }selectImports方法返回了這兩個(gè)類:ConfigurationPropertiesBeanRegistrar和ConfigurationPropertiesBindingPostProcessorRegistrar,是何時(shí)加載的,我們只需要看這個(gè)類ConfigurationPropertiesBeanRegistrar即可:
/*** {@link ImportBeanDefinitionRegistrar} for configuration properties support.*/ public static class ConfigurationPropertiesBeanRegistrarimplements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(EnableConfigurationProperties.class.getName(), false);List<Class<?>> types = collectClasses(attributes.get("value"));for (Class<?> type : types) {// 類的@ConfigurationProperties的prefix屬性值,默認(rèn)為空字符串String prefix = extractPrefix(type);// prefix和類名的拼接String name = (StringUtils.hasText(prefix) ? prefix + "-" + type.getName(): type.getName());if (!registry.containsBeanDefinition(name)) {// 注冊(cè)方法:根據(jù)找到的類名name和type,將加入注解@ConfigurationProperties的類加入spring容器里面registerBeanDefinition(registry, type, name);}}} }另外還有這個(gè)類:ConfigurationPropertiesBindingPostProcessorRegistrar,剛剛沒(méi)有分析,看了下源碼,其實(shí)他做的事情就是通過(guò) ConfigurationPropertiesBindingPostProcessor 將配置文件當(dāng)中的屬性值賦予到加了@ConfigurationProperties的注解的類的屬性上。
/*** {@link ImportBeanDefinitionRegistrar} for binding externalized application properties* to {@link ConfigurationProperties} beans.** @author Dave Syer* @author Phillip Webb*/ public class ConfigurationPropertiesBindingPostProcessorRegistrarimplements ImportBeanDefinitionRegistrar {/*** The bean name of the {@link ConfigurationPropertiesBindingPostProcessor}.*/public static final String BINDER_BEAN_NAME = ConfigurationPropertiesBindingPostProcessor.class.getName();private static final String METADATA_BEAN_NAME = BINDER_BEAN_NAME + ".store";@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {if (!registry.containsBeanDefinition(BINDER_BEAN_NAME)) {BeanDefinitionBuilder meta = BeanDefinitionBuilder.genericBeanDefinition(ConfigurationBeanFactoryMetaData.class);BeanDefinitionBuilder bean = BeanDefinitionBuilder.genericBeanDefinition(ConfigurationPropertiesBindingPostProcessor.class);bean.addPropertyReference("beanMetaDataStore", METADATA_BEAN_NAME);registry.registerBeanDefinition(BINDER_BEAN_NAME, bean.getBeanDefinition());registry.registerBeanDefinition(METADATA_BEAN_NAME, meta.getBeanDefinition());}}}?
參考:
https://www.jianshu.com/p/7f54da1cb2eb
總結(jié)
以上是生活随笔為你收集整理的关于 @EnableConfigurationProperties 注解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 虚幻引擎编辑器开发基础(一)
- 下一篇: 塑造运动的包豪斯平面设计实例