一、两种配置文件获取值的方式
因为普遍属性比较简单,可能复杂属性有些小伙伴们不知道怎么获取。因此我将application.yml和application.properties两种配置文件中对象复杂属性定义的内容列举出来:
application.properties文件:
#自定义list集合
person.lists=a,b,c
#自定义map集合
person.maps.k1=va2
person.maps.k2=v2
#自定义person中的dog对象属性
person.dog.name=毒瓦斯
person.dog.age=8
application.yml文件:
#自定义map集合
#缩进方式
person:
maps:
k1: v2
k2: v3
#行内方式
person:
maps:{k1: v2,k2: v3}
#自定义数组
#缩进方式
person
lists:
- 镰刀湾
- 瓦斯的
#行内方式
person:
lists:[镰刀湾,瓦斯的]
#自定义对象属性
person:
dog:
name: awdwa
age: 11
1、方式一 通过@ConfigurationProperties注解
@ConfigurationProperties注解作用是告诉springboot将本类中的所有属性与配置文件中的属性进行绑定,它需要提供prefix属性,可通过统一前缀批量将类中属性和配置文件中属性进行绑定,使用该方式的时候需要引入配置文件处理器依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
并且使用添加@Component、@Configuration或者@EnableConfigurationProperties注解,将类作为容器中的组件,才能使用容器中的功能。
示例代码如下:
package com.example.demo.entity;
import org.springframework.stereotype.Component;
@Component
@Data
public class Dog {
private String name;
private int age;
}
1.1、使用@Component注解
package com.example.demo.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "person")
@Data
public class Person {
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
1.2、使用@configuration注解:
package com.example.demo.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@configuration
@ConfigurationProperties(prefix = "person")
@Data
public class Person {
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
1.3、使用@EnableConfigurationProperties注解
package com.example.demo.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "person")
@Data
public class Person {
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
@SpringBootApplication
@EnableConfigurationProperties(Person.class)
public class DemoApplication {
@Autowired
private Person person;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
@ResponseBody
public String hello() {
System.out.println("person" + person);
return "hello world";
}
public static void main(String[] args) {
//SpringApplication.run(TestProperty1.class, args);
new SpringApplicationBuilder(DemoApplication.class).web(SERVLET).run(args);
}
}
2、方式二 通过@Value注解
@Value注解类似在原始spring项目在配置文件中配置bean标签,在bean标签中配置了properties标签,并提供value属性值,例如:
<bean class="xxx">
<properties name="xxx" value=""/>
</bean>
@Value注解相当于这个properties标签中的value属性值。
使用@Value注解不能通过前缀批量将类中所有属性与配置文件中特定属性绑定,它支持使用${key}(从环境变量、配置文件中获取值)、#{SpEl}等。
比如:
@Value("${person.last-name}")
private String name;
@Value("#{11*2}") /**为spring表达式
private int age;
@Value("true")
private boolean flag;
将配置文件中的属性绑定到类中的属性时,对于对象属性,如果键包含除小写字母数字字符或-以外的任何字符,则需要使用括号表示法,以便保留原始值。如果键未被[]包围,则将删除任何非字母数字或-的字符。比如map属性:
#yml文件写法
#自定义map集合
person:
maps:
"[/key1]": value1
/key3: value3
k2: v2
#properties文件写法
#自定义map集合
person.maps.[/key1]=va2
person.maps./key3=v2
那么使用注解获取到的map集合内容为maps={/key1=va2, key3=v2}
二、@ConfigurationProperties和@Value注解不同
2.1、松散绑定
比如类中定义了一个属性,属性名为firstName,如果使用@ConfigurationProperties,那么配置文件中,该属性可以写成如下形式:
person.firstName:使用标准方式
person.first-name:大写用-,建议在.properties和.yml文件中使用。
person.first_name:大写用_,它是用于.properties和.yml文件的可选格式。
PERSON.FIRST_NAME 大写格式,建议在使用系统环境变量时使用。
但是如果使用@Value注解,那么只能写成@Value("${person.firstName}")。
每个属性源的宽松绑定规则:
2.2、JSR303数据校验
@ConfigurationProperties注解支持JSR303数据校验,意味着进行数据校验的属性必须符合规则才给予通过,否则报错。比如给类中的某个属性添加@Email注解,则规定,该属性值必须符合邮箱格式才进行通过。查看代码:
@Validated
public class Person {
@Value("${person.last-name}")
@Email
private String name;
}
2.3、关于绑定类中的属性是否需要提供set、get方法
这个情况只适应于使用@ConfigurationProperties注解。由于绑定是通过标准javaBean属性,因此绝大情况下属性都需要提供setter和getter方法,除以下情况可以省略setter方法:
- 集合或者数组 可以通过索引(通常使用yaml)或使用单个逗号分隔值(属性)访问。对于数组属性,setter方法是强制的。我们建议始终为此类类型添加setter方法。如果初始化集合,请确保它不是不可变的。
- 初始化了嵌套的POJO属性,例如:person类中有一个属性:private Dog dog=new Dog();则不需要setter方法,但是是private Dog dog;则需要提供setter方法。如果希望绑定器使用其默认构造函数动态创建实例,则需要一个setter方法。
- 最后,只考虑标准的JavaBean属性,不支持对静态属性的绑定。
三、配置文件占位符
springboot配置文件中允许使用随机数或者在配置文件中引用前面配置过的属性来作为占位符。
比如使用随机数的占位符:
${random.int}
${random.long}
${random.value}
${random.uuid}
${random.int(10)}
${random.int[1024,65523]}
比如在文件中引用前面配置过的属性作为占位符:
app.name=MyApp
app.decription=${app.name} is a SpringBoot Application
如果配置文件上下文没有该属性时,我们随便输入一个属性名,那么它将会把这个属性名打印出来,比如:
app.name=Myapp
app.decription=${MyProject} is a SpringBoot Application
那么使用注解获取app.decription这个属性值时,打印的结果为:MyProject is a SpringBoot Application
我们还可以为这个配置文件上下文都没有的属性值赋值。比如如下操作:
app.name=Myapp
app.decription=${MyProject:customProject} is a SpringBoot Application
那么使用注解获取app.decription这个属性值时,打印的结果为:customProject is a SpringBoot Application