c语言sscanf函数的用法是什么
390
2022-09-17
《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?
一、@Value
通过@Value我们可以直接将属性值注入到IOC容器的相应bean 中,业务上我们注入单个属性时最常使用的也是这种方式。
不过,有时使用@Value("${property}")注解来注入配置属性有时会很麻烦,尤其是当要使用多个属性 或 数据本质上是分层的 时。
所以,Spring Boot 提供了一种使用属性的替代方法,可以让强类型 bean 管理和验证应用程序的配置。
使用方式:
需要使用到属性的JavaBean中:
@Value("${test.test}")private String test;
yaml文件:
test: test: test-resources/
二、@ConfigurationProperties
@ConfigurationProperties加载配置是通过BeanPostProcessor实现,其对应的Bean的后置处理器为ConfigurationPropertiesBindingPostProcessor。也就是说在bean被实例化后,会调用后置处理器,递归的查找属性,通过反射机制注入值,因此属性需要提供setter和getter方法。 此外,针对此种属性注入的方式,SpringBoot支持Relaxed Binding,即只需保证配置文件的属性和setter方法名相同即可。
在SpringBoot官方文档中有几个注意点:
属性必须要有getter、setter方法;如果属性的类型是集合,要确保集合是不可变的;如果使用Lombok自动生成getter/setter方法,一定不要生成对应的任何构造函数,因为Spring IOC容器会自动使用它来实例化对象。使用JavaBean属性绑定的方式只针对标准 Java Bean 属性,不支持对静态属性的绑定。
当我们使用@ConfigurationProperties注解进行属性注入时,记得在pom.xml文件中添加spring-boot-configuration-processor依赖,
否则相应类上会有一行红色的异常信息,具体如下:
Spring Boot Configuration Annotation Processor
并且在pom中加上spring-boot-configuration-processor依赖之后,我们使用@ConfigurationProperties注解注释的配置类中的字段,在yaml文件中会自动带出提示 / 补全。
1、@EnableConfigurationProperties
Spring考虑到带有注释@ConfigurationProperties的类可能不适合扫描(比如:我正在开发自己的自动配置或希望有条件地启用它们),所以Spring并不会自动扫描带有注释@ConfigurationProperties的类。
在这些情况下,推荐使用@EnableConfigurationProperties注解指定要处理的类型列表(即:将@ConfigurationProperties注释的类加到Spring IOC容器中)。一般通过将@EnableConfigurationProperties加在@Configuration类上完成。
使用方式1:@EnableConfigurationProperties + @Configuration + @ConfigurationProperties
如下例所示:
@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties(SomeProperties.class)public class MyConfiguration {}
@ConfigurationProperties(prefix = "some.properties")public class SomeProperties { private String test;}
这种方式在Spring源码中被广泛使用:
比如:Spring MVC的配置类(WebMvcProperties)
其在WebMvcAutoConfiguration类的静态内部类WebMvcAutoConfigurationAdapter上被通过@Configuration + @EnableConfigurationProperties的方式被注入到Spring IOC容器中。
使用方式2:@Configuration + @ConfigurationProperties
直接将@Configuration注解 和 @ConfigurationProperties注解加在JavaBean上,让Spring IOC可以自动扫描到 @ConfigurationProperties注解标注的类。
@Configuration(proxyBeanMethods = false)@ConfigurationProperties(prefix = "some.properties")public class SomeProperties { private String test;}
2、宽松绑定(Relaxed Binding)
Spring Boot 中使用一些宽松的规则将环境属性(可以理解为配置文件application.yml中的属性)绑定到bean中,也就是说:yaml文件中的属性名称和 JavaBean属性名称@ConfigurationProperties之间不需要完全匹配。包括:
破折号分隔的环境属性(context-path绑定到contextPath)大写环境属性(PORT绑定到port)
例如,考虑以下@ConfigurationProperties类:
@ConfigurationProperties(prefix = "my.main-project.person")public class MyPersonProperties { private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; }}
使用上述代码时,可以使用以下属性名称:
Property | Note |
my.main-project.person.first-name | Kebab case,通常使用在 |
my.main-project.person.firstName | 标准驼峰方式 |
my.main-project.person.first_name | 下划线表示法,在 |
MY_MAINPROJECT_PERSON_FIRSTNAME | 大写格式,在使用系统环境变量时推荐使用 |
注意:@ConfigurationProperties注解中prefix的值必须是 kebab 大小写(小写并用 分隔-,例如my.main-project.person)
每种属性源的宽松绑定规则
3、JSR-303对@ConfigurationProperties验证
每当使用 Spring 的注解@Validated进行注解时,Spring Boot 都会尝试验证类。我们可以直接在配置类上使用 JSR-303约束注释。
@ConfigurationProperties("my.service")@Validatedpublic class MyProperties { @NotNull private InetAddress remoteAddress; // getters/setters...}
注:注释@Bean创建配置属性的方法来也可以触发验证@Validated
4、第三方配置
@ConfigurationProperties除了用于注释类之外,还可以在公共@Bean方法上使用它。当想要将属性绑定到我们无法控制的第三方组件时,这样做会特别有用。
@Configuration(proxyBeanMethods = false)public class ThirdPartyConfiguration { @Bean @ConfigurationProperties(prefix = "another") public AnotherComponent anotherComponent() { return new AnotherComponent(); }}
三、@Value和@ConfigurationProperties的区别?
@ConfigurationProperties注解支持属性文件和javabean的映射;而@Value支持spel表达式。@ConfigurationProperties注解支持全量的属性 宽松绑定方式;而@Value只推荐使用标准的kebab-case方式(仅使用小写字母和-),例如:@Value("{demo.item-price}")可以提取demo.item-price和demo.itemPrice。对于多个属性映射,并且属性常常被复用时,推荐使用@ConfigurationProperties;只读取单个属性使用@Value更简单方便。
四、SpringBoot配置加载优先级
移步至:SprintBoot:配置文件加载优先级(含服务注册中心nacos)
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~