关于 @EnableConfigurationProperties 注解
先說作用:
@EnableConfigurationProperties注解的作用是:使使用 @ConfigurationProperties 注解的類生效。
說明:
用springboot開發的過程中,我們會用到@ConfigurationProperties注解,主要是用來把properties或者yml配置文件轉化為bean來使用的,而@EnableConfigurationProperties注解的作用是@ConfigurationProperties注解生效。
如果只配置@ConfigurationProperties注解,在IOC容器中是獲取不到properties配置文件轉化的bean的,當然在@ConfigurationProperties加入注解的類上加@Component也可以使交于springboot管理。
說白了 @EnableConfigurationProperties 相當于把使用 @ConfigurationProperties 的類進行了一次注入。
?
測試:
@ConfigurationProperties?與?@EnableConfigurationProperties?的關系。
@EnableConfigurationProperties?文檔中解釋:
當@EnableConfigurationProperties注解應用到你的@Configuration時, 任何被@ConfigurationProperties注解的beans將自動被Environment屬性配置。 這種風格的配置特別適合與SpringApplication的外部YAML配置進行配合使用。
測試發現:
1.使用?@EnableConfigurationProperties?進行注冊
自動配置設置
service.properties.name=my-test-name service.properties.ip=192.168.1.1 service.user=kayle service.port=8080一切正常,但是 HelloServiceAutoConfiguration 頭部不使用?@EnableConfigurationProperties,測訪問報錯。
2.不使用?@EnableConfigurationProperties?進行注冊,使用?@Component?注冊
@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 測啟動報錯。
由此證明,兩種方式都是將被 @ConfigurationProperties 修飾的類,加載到 Spring Env 中。
測試環境:SpringBoot1.5
?
@EnableConfigurationProperties是怎么加載的
通過查看@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 {};}通過分析自動配置可以知道,肯定是這個類EnableConfigurationPropertiesImportSelector起的作用;@Import的作用就是把這個ImportSelector的selectImprts()方法返回的類名的類加載到IOC容器中。
/*** 將ConfigurationPropertiesBeanRegistrar、ConfigurationPropertiesBindingPostProcessorRegistrar這兩個類注冊到容器中。*/ @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方法返回了這兩個類:ConfigurationPropertiesBeanRegistrar和ConfigurationPropertiesBindingPostProcessorRegistrar,是何時加載的,我們只需要看這個類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屬性值,默認為空字符串String prefix = extractPrefix(type);// prefix和類名的拼接String name = (StringUtils.hasText(prefix) ? prefix + "-" + type.getName(): type.getName());if (!registry.containsBeanDefinition(name)) {// 注冊方法:根據找到的類名name和type,將加入注解@ConfigurationProperties的類加入spring容器里面registerBeanDefinition(registry, type, name);}}} }另外還有這個類:ConfigurationPropertiesBindingPostProcessorRegistrar,剛剛沒有分析,看了下源碼,其實他做的事情就是通過 ConfigurationPropertiesBindingPostProcessor 將配置文件當中的屬性值賦予到加了@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
總結
以上是生活随笔為你收集整理的关于 @EnableConfigurationProperties 注解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚幻引擎编辑器开发基础(一)
- 下一篇: CUBA - 一个卓越的 Java 快速