springboot使用@ConfigurationProperties实现自动绑定配置参数属性
作者:曹朋羽
@ConfigurationProperties使用
@ConfigurationProperties是 springboot提供用于将配置文件中的属性值映射到 Java bean对象上。通过使用该注解,我们可以方便地将属性文件中的值绑定到一个实例化的类对象上,从而方便地在应用程序中使用这些属性。
@ConfigurationProperties注解有一个参数prefix用来指定属性公共前缀
@Configuration @ConfigurationProperties(prefix = "myconfig") @Data public class MyConfigProperty { private int port; //找不到的属性不会注入 private String hhh; }
一般作为属性注入对象,首先定义成一个@Configuration。然后使用@ConfigurationProperties指定关联属性的前缀。
这样如果配置文件中有myconfig.port的值就会自动绑定到MyConfigProperty类的port属性上。前提要有对应的set方法。
除了在类上标注外,还可以在@Bean方法上
@Configuration public class MyConfigByMethod { @Bean @ConfigurationProperties(prefix = "myconfig") public MyConfig myConfig(){ return new MyConfig(); } }
观察spring的源码,还会使用@EnableConfigurationProperties引入被@ConfigurationProperties修饰的bean
框架自动装配解析
在springboot框架自动装配中有一个内置的用来处理@ConfigurationProperties注解的配置类ConfigurationPropertiesAutoConfiguration,该配置类引入@EnableConfigurationProperties,然后间接引入EnableConfigurationPropertiesRegistrar,EnableConfigurationPropertiesRegistrar在configuration初始化的时候会调用其registerBeanDefinitions()方法进行配置类中扩展beanDef的加载。
EnableConfigurationPropertiesRegistrar#registerBeanDefinitions
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { registerInfrastructureBeans(registry); registerMethodValidationExcludeFilter(registry); ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry); getTypes(metadata).forEach(beanRegistrar::register); } private Set<Class<?>> getTypes(AnnotationMetadata metadata) { return metadata.getAnnotations().stream(EnableConfigurationProperties.class) .flatMap((annotation) -> Arrays.stream(annotation.getClassArray(MergedAnnotation.VALUE))) .filter((type) -> void.class != type).collect(Collectors.toSet()); } static void registerInfrastructureBeans(BeanDefinitionRegistry registry) { ConfigurationPropertiesBindingPostProcessor.register(registry); BoundConfigurationProperties.register(registry); }
这里主要会完成两件事件:
1、registerInfrastructureBeans会将ConfigurationPropertiesBindingPostProcessor注册到容器中,这是一个后置处理其,属性的赋值会在其后置方法里完成。
2、注册合适的ConfigurationProperties类型bean, 当前metadata是正在初始化的Configuration类,然后从其注解上获取带有EnableConfigurationProperties注解作为bean定义加载到容器中。
来看几个自动装配的例子:
ServletWebServerFactoryAutoConfiguration
- ServletWebServerFactoryAutoConfiguration上带有@EnableConfigurationProperties(ServerProperties.class)注解,则ServerProperties会作为一个bean进行处理。
- ServerProperties上配置有@ConfigurationProperties(prefix = “server”, ignoreUnknownFields = true),我们场景的server.port属性就会注入到ServerProperties.port属性上。
DataSourceAutoConfiguration
@EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceAutoConfiguration {} @ConfigurationProperties(prefix = "spring.datasource") public class DataSourceProperties{}
DataSourceProperties会被做为一个bean加载,"spring.datasource"下的属性会注入到DataSourceProperties属性中。
ConfigurationPropertiesBindingPostProcessor
ConfigurationPropertiesBindingPostProcessor是一个bean后置处理器,在bean实例化后会调用其后置方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName)); return bean; }
ConfigurationPropertiesBean.get()方法会判断当前bean是否有ConfigurationProperties注解,如果有会进行对应的属性绑定。
最后使用org.springframework.boot.context.properties.bind.Binder类进行属性绑定。
这里ConfigurationProperties会有两部分,一是框架通过autoConfig自动装配的,一种是我们自己显示使用@ConfigurationProperties修饰的bean。
这里看到我们在自定义@ConfigurationProperties时候不一定非用@Configuration进行修饰,只要当前类能被解析成一个bean,都会调用该后置方法进行对应配置属性的赋值。
属性元数据信息
可配置的属性在每个jar包META-INFO/spring-configuration-metadata.json文件。这样一般在IDEA配置application文件时候都能根据该文件里的元数据信息进行提示配置。
例如server.port配置在spring-boot-autoconfigure.jar包中
{ "name": "server.port", "type": "java.lang.Integer", "description": "Server HTTP port.", "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties", "defaultValue": 8080 },
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- SpringBoot中的@ConfigurationProperties注解的使用
- SpringBoot中@ConfigurationProperties自动获取配置参数的流程步骤
- Springboot之@ConfigurationProperties注解解读
- Springboot中@ConfigurationProperties轻松管理应用程序的配置信息详解
- SpringBoot中@Value获取值和@ConfigurationProperties获取值用法及比较
- springboot中@ConfigurationProperties无效果的解决方法
- SpringBoot中的@ConfigurationProperties注解解析