Spring Boot属性文件:@ConfigurationProperties示例
如果我们在应用程序中使用一些配置参数,那么最好是外部化配置,而不是硬编码值。在Spring Boot中,外部化配置的一种方法是使用属性文件或者YAML文件。在本文中,我们将介绍如何在Spring Boot中使用属性文件以及如何从属性文件中读取属性值。
Spring Boot application.properties文件
在Spring Boot中,SpringApplication自动从application.properties文件加载属性,并将其添加到Spring Environment。我们应该将application.properties文件保存在以下位置之一。
1.当前目录的/ config子目录
2.当前目录
3.一个classpath / config包
4. classpath根
该列表按优先级排序(在列表较高位置定义的属性将覆盖在较低位置定义的属性)。
请注意,我们还可以使用YAML(.yml)文件代替" .properties"文件。
创建application.properties文件
在src / main / resources目录中创建application.properties文件,因为该属性文件应位于类路径中。
将一些键值对添加到application.properties文件。
springboot.app.name=SpringBootProject springboot.welcome.message=Welcome User
使用YAML文件
我们也可以在同一位置创建application.yml文件而不是application.properties。 YAML是JSON的超集,它是用于指定层次结构配置数据的便捷格式。
示例application.yml文件
springboot: app: name:SpringBootProject welcome: message:Welcome User
切换到另一个文件名
如果要将配置文件命名为application.properties以外的名称,则可以通过指定spring.config.name环境属性来实现。
java -jar SpringBootProject.jar --spring.config.name=myprops
我们还可以通过使用spring.config.location环境属性来引用显式位置
java -jar SpringBootProject.jar --spring.config.location=classpath:/default.properties, classpath:/override.properties
使用@Value注释注入配置值
准备好属性文件后,即可在Spring Bean中使用它。从属性中注入属性值的一种方法是使用@Value注释。使用@Value注释,我们可以读取环境变量或者系统变量。
这是一个类,其中在字段上使用@Value注释,以通过使用属性的键来注入属性值。
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class WelcomeConfiguration { @Value("${springboot.app.name}") private String name; @Value("${springboot.welcome.message}") private String message; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
我们可以使用以下应用程序类对其进行测试。
import org.netjs.SpringBootApp.controller.WelcomeConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootAppApplication implements CommandLineRunner{ @Autowired WelcomeConfiguration config; public static void main(String[] args) { SpringApplication.run(SpringBootAppApplication.class, args); } @Override public void run(String... args) throws Exception { // displaying property values System.out.println("Application Name- " + config.getName()); System.out.println("Welcome Message- " + config.getMessage()); } }
输出:
Application Name- SpringBootProject Welcome Message- Welcome User
使用@ConfigurationProperties注释的应用程序配置
如果我们具有多个属性或者数据本质上是分层的,则使用@Value(" $ {property}")注释来注入配置属性将变得乏味。 Spring Boot提供了更好的替代@ConfigurationProperties注释,以从属性文件读取配置值。
要了解如何使用@ConfigurationProperties从Spring Boot应用程序的属性文件中读取值,请创建src / main / resources / application.properties文件,该文件具有不同数据类型的值,并且本质上也是分层的。
springboot.app.name=SpringBootProject springboot.app.creator=theitroad springboot.app.active=true springboot.app.pages=4 #List springboot.app.citycodes=US,IN,CN,AU #-- Nested Properties- springboot.app.inner.strproperty=test #List springboot.app.inner.datalist[0]=list0 springboot.app.inner.datalist[1]=list1 #Map springboot.app.inner.propmap.key1=value1 springboot.app.inner.propmap.key2=value2 springboot.app.inner.propmap.key3=value3
接下来是使用@ConfigurationProperties注释进行注释的类,该类是用于外部化配置的注释,并绑定来自.properties或者YAML文件的某些外部属性。
import java.util.List; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix="springboot.app") public class WelcomeConfiguration { private String name; private String creator; private boolean active; private int pages; private List<String> cityCodes; private final Inner inner = new Inner(); public static class Inner{ private String strProperty; private List<String> dataList; private Map<String, String> propMap; public void setStrProperty(String strProperty) { this.strProperty = strProperty; } //.. getters and setters } public String getName() { return name; } public Inner getInner() { return inner; } //.. getters and setters }
这里要注意的几点是
使用前缀元素,我们可以指定可以绑定到POJO的属性。它还可以照顾到分层属性(如示例中的静态内部类所做的那样)。
属性值绑定以类型安全的方式完成。正如我们在POJO类中看到的那样,存在不同类型的字段String,boolean,int,List,Map,所有这些字段都是通过将属性转换为必需的类型来绑定的。
即使属性文件中的键全部为小写,也已正确绑定到POJO类中的驼峰对应。
SpringBootApplication类
使用下面的类,我们可以显示绑定的属性。
import org.netjs.SpringBootApp.controller.WelcomeConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootAppApplication implements CommandLineRunner{ @Autowired WelcomeConfiguration config; public static void main(String[] args) { SpringApplication.run(SpringBootAppApplication.class, args); } @Override public void run(String... args) throws Exception { // displaying property values System.out.println("Application Name- " + config.getName()); System.out.println("Creator- " + config.getCreator()); System.out.println("Active- " + config.isActive()); System.out.println("Pages- " + config.getPages()); System.out.println("Codes- " + config.getCityCodes()); System.out.println("Strporoperty- " + config.getInner().getStrProperty()); System.out.println("Data List- " + config.getInner().getDataList()); System.out.println("Prop Map- " + config.getInner().getPropMap()); } }
输出:
Application Name- SpringBootProject Creator- theitroad Active- true Pages- 4 Codes- [US, IN, CN, AU] Strporoperty- test Data List- [list0, list1] Prop Map- {key1=value1, key2=value2, key3=value3}
@ConfigurationProperties验证
每当使用Spring的@Validated注释对@ConfigurationProperties类进行注释时,Spring Boot就会尝试对其进行验证。支持JSR-303 javax.validation,并且可以使用JSR-303 javax.validation约束
注释直接在配置类上。
添加spring-boot-starter-validation以在类路径上获得兼容的JSR-303实现。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
在字段上添加@Validated注释和验证约束。
import java.util.List; import java.util.Map; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @ConfigurationProperties(prefix="springboot.app") @Validated public class WelcomeConfiguration { @NotNull private String name; private String creator; private boolean active; private int pages; @NotEmpty private List<String> cityCodes; //it’s good practice to annotate the nested properties // associated field as @Valid @Valid private final Inner inner = new Inner(); public static class Inner{ @Size(min = 10, max = 20) private String strProperty; private List<String> dataList; private Map<String, String> propMap; //getters and setters } //getters and setters }
现在,如果从应用程序属性文件中删除了城市代码,并且strProperty字段的值是" test"(根据值的验证长度,该值应在10到20的范围内),则我们将收到以下错误消息。
*************************** APPLICATION FAILED TO START *************************** Description: Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'springboot.app' to org.netjs.SpringBootApp.controller.WelcomeConfiguration failed: Property: springboot.app.inner.strProperty Value: test Reason: size must be between 10 and 20 Property: springboot.app.cityCodes Value: [] Reason: must not be empty Action: Update your application's configuration