配置文件
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
- application.properties
语法结构 : key=value - application.yml
语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都自动配置好了;
YAML
YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。
在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
YAML A Markup Language :是一个标记语言
YAML isnot Markup Language :不是一个标记语言
标记语言
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,对比下yaml和xml
yaml配置:
server:
prot: 8080
xml配置:
<server>
<port>8081<port>
</server>
YAML语法
基础语法:
k:(空格) v
以此来表示一对键值对(空格不能省略);以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
注意 :属性和值的大小写都是十分敏感的。例子:
server:
port: 8081
path: /hello
值的写法
字面量:普通的值 [ 数字,布尔值,字符串 ]
k: v
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
“” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 : name: “wen \n li” 输出 : wen 换行 li
‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 : name: ‘wen \n li’ 输出 : wen \n li
对象、Map(键值对)
k:
v1:
v2:
在下一行来写对象的属性和值得关系,注意缩进;比如:
student:
name: chaowenli
age: 20
行内写法
student: {name: chaownli,age: 20}
数组( List、set )
用 - 值表示数组中的一个元素,比如:
pets:
- cat
- dog
- pig
行内写法
pets: [cat,dog,pig]
修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
server.port=8081
注入配置文件
程序实现
- 如果要使用properties配置文件可能导入时存在乱码现象 , 需要在IDEA中进行调整 , 这里直接使用yml文件 , 将默认的 application.properties后缀修改为yml
- 导入配置文件处理器
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 编写yml 配置文件
person:
name: 晁文利
age: 20
happy: true
birth: 2000/1/1
maps: {h1: hello1,h2: hello2}
hobbys: [code,music]
dog:
name: 小黄
age: 2
- 在SpringBoot的主程序的同级目录下建包,只有这样,主程序才会对这些类生效 ;
建一个pojo的包放入Person类和Dog类;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*/
@Component //被容器托管 注册bean
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> hobbys;
private Dog dog;
// 有参,无参构造
//get,set方法
//toString方法
}
public class Dog {
private String name;
private Integer age;
//有参,无参构造
//get,set方法
//toString方法
}
- 确认无误后,到测试单元中进行测试,看是否注入成功!
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo05ApplicationTests {
@Autowired
Person person;
@Test
public void contextLoads() {
System.out.println(person);
}
}
运行结果
其他实现方式
上面采用的方法都是最简单的方式,开发中最常用的;
再看看其他的实现方式,道理都是相同得,写还是那样写;
配置文件除了yml还有常用的properties , properties配置文件在写中文的时候,会有乱码 , 需要去IDEA中设置编码格式为UTF-8;
settings–>FileEncodings 中配置;
类和配置文件直接关联着 , 这里使用的是@configurationProperties的方式,还有一种方式是使用@value
@Component //被容器托管
//@ConfigurationProperties(prefix = "person") //推荐使用
public class Person {
//直接使用@value
@Value("${person.name}") //从配置文件中取值
private String name;
@Value("#{1*2}")
......
}
运行结果
这个使用起来并不友好,需要为每个属性单独注解赋值,比较麻烦;来看功能对比图
- cp只需要写一次即可 , value则需要每个字段都添加
- 松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, -
后面跟着的字母默认是大写的。这就是松散绑定 - JSR303数据校验 , 就是在字段是增加一层过滤器验证 , 保证数据的合法性
- 复杂类型封装,yml中可以封装对象 , 使用@value就不支持
结论:
- 配置yml和配置properties都可以获取到值 , 强烈推荐 yml
- 如果在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value
- 如果我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用@configurationProperties,不要犹豫!
JSR303数据校验
spring-boot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。这里来写个注解让name只能支持Email格式
@Component //被容器托管
@ConfigurationProperties(prefix = "person") //推荐使用
@Validated //可以支持JSR303数据校验
public class Person {
@Email
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> hobbys;
private Dog dog;
// 有参,无参构造
//get,set方法
//toString方法
}
运行结果
使用数据校验,可以保证数据的正确性;
加载指定配置文件
@PropertySource :加载指定的配置文件;
@configurationProperties默认从全局配置文件中获取值;
在resources目录下新建一个person.properties文件
name=princessli
然后在代码中指定加载person.properties文件
@Component //注册bean
@PropertySource(value = "classpath:person.properties")
public class Person {
@Value("${name}")
private String name;
...
}
测试结果
配置文件占位符
随机数
${random.value}、${random.int}、${random.long}、${random.int(10)}等等
占位符引用其他属性的值,如果不存在可以设置默认值
#可以在yml文件中放置占位符
person:
name: 晁文利${random.uuid}
age: ${random.int}
happy: true
birth: 2000/1/1
maps: {h1: hello1,h2: hello2}
hobbys: [code,music]
dog:
name: 小黄
age: 2
运行结果