SpringBoot(三) — 配置文件详解
文章目录
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
因为SpringBoot在底层都给我们自动配置好了,因此配置文件的作用 :修改SpringBoot自动配置的默认值,通常我们使用的配置文件有两种,application.properties
和application.yml
(后缀名yml,yaml是一样的),为了配置方便快捷,我们这里主要讲解application.yml
。
注意:如果配置文件properties和yml都存在,则以properties配置文件为主
- application.properties
- 语法结构 :key=value
- application.yml
- key:空格 value
yaml概述
在这里我们介绍一种新的语言 — yaml,这种语言以数据作为中心,而不是以标记语言为重点。以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,对比下yaml和xml。
xml配置:
<server>
<port>8081<port>
</server>
yaml配置:
server:
prot: 8080
yaml基础语法
- 以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
- 属性和值的大小写都是十分敏感的。
- 空格不能省略,特别是
:
后面需要一个空格
字面量:普通的值 [ 数字,布尔值,字符串 ]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号:
k: v
对象、Map(键值对)
k:
v1:
v2:
换行来写对象的属性和值得关系,注意缩进:
people:
name: tom
age: 18
或者采用行内写法:
people: {name: tom,age: 18}
数组( List、set )
用 - 值表示数组中的一个元素:
pets:
- cat
- dog
- pig
注意点
-
“ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: “巴啦啦 \n 能量” 输出 :巴啦啦 换行 能量
-
‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘巴啦啦 \n 能量’ 输出 :巴啦啦 \n 能量
配置详解
1. 修改配置文件
我们知道,当我们不做任何配置的时候,SpringBoot会自动配置,那时我们的端口号就是内置的的tomcat端口号8080,根路径为/
,如果不想自动配置,可以自已设置内嵌Tomcat端口号以及上下文根(上下文根必须加/
)
application.properties配置文件写法:
#设置内嵌Tomcat端口号
server.port=8081
#设置上下文根
server.servlet.context-path=/springboot
application.yaml配置文件写法(注意:
后的空格):
server:
port: 8081
servlet:
context-path: /springboot
查看结果:
-
端口号为8081:
-
访问路径根路径为
/springboot
:-
浏览器输入 http://localhost:8081/hello 访问失败
-
浏览器输入 http://localhost:8081/springboot/hello 访问成功
-
2. 注释配置文件
当我们想注释某配置文件后面加--
多环境核心配置文件
1. 多环境核心配置文件properties
工作中的开发环境:开发、测试、准生产和生产四种环境,ip地址用户环境等可能都不一样,所以需要配置四个环境
当我们需要利用开发环境的配置时,就在application.properties
中书写active的激活配置文件为:
#springboot主核心配置文件
#激活使用的配置文件
spring.profiles.active=dev
但是配置文件application-xxx
后面的xxx必须是英文不能是中文
2. 多环境核心配置文件yml
yml支持多文档块方式,通过—可以把一个yml文档分割为多个,并可以通过spring.profiles.active
属性指定使用哪个配置文件
server:
port: 8081
spring:
profiles:
active: prod #指定使用哪个环境
---
server:
port: 8083
spring:
profiles: dev #指定属于哪个环境
---
server:
port: 8084
spring:
profiles: prod #指定属于哪个环境
SpringBoot配置文件的加载顺序
spring boot项目中同时存在application.properties和application.yml文件时,两个文件都有效,但是application.properties的优先级会比application.yml高。
项目内配置文件加载顺序
SpringBoot
项目启动会扫描以下位置的application.properties
或者application.yml
文件作为SpringBoot
的默认配置文件,具体的目录位置见下图。
- file:./config/ ( 项目根路径下的config文件夹)
- file:./ (项目根路径)
- classpath:/config/ (类路径下的config文件夹)
- classpath:/ (类路径)
配置文件的优先级就是8081,8082,8083,8084,优先级由高到底,高优先级的配置会覆盖低优先级的配置,没有的配置进行互补配置。
注意:不是类路径下的配置文件在打包时,如果不做配置是不会打包进jar中的,也会是说前两个配置在项目打包后,包中是不存在的,所以尽量不要用前两个位置
外部配置文件
-
命令行参数
项目打包好以后,我们可以使用命令行参数的形式,来改变想改变的几个参数,直接在启动命令后添加启动参数,如果有多个配置项,可以用空格分开。例如我们运行
springboot-configuration.jar
这个jar包,通过--server.port=8088 --server.servlet.context-path=/spring
指定,注意多参数有空格隔开:java -jar springboot-configuration.jar --server.port=8088 --server.servlet.context-path=/spring
-
spring.config.location
在第一种情况下,如果参数数量过多,我们就要考虑配置文件了,我们在启动项目的时候可以用
spring.config.location
来指定配置文件的新位置。指定的配置文件和jar包中默认加载的配置文件共同起作用形成互补配置。指定配置文件从D盘下读取: java -jar springboot-configuration.jar --spring.config.location=D:/application.properties
相同配置,外部指定的配置文件优先级最高
自定义配置
yaml文件强大的地方在于,他可以给我们的实体类直接注入匹配值!
1. @value
-
在包
entity
包下创建实体类Dog
:import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Component //注册bean到容器中 @Data //有参无参构造、get、set方法、toString()方法 @AllArgsConstructor @NoArgsConstructor public class Dog { private String name; private Integer age; }
-
使用@value给bean注入属性值:
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Component //注册bean到容器中 @Data //有参无参构造、get、set方法、toString()方法 @AllArgsConstructor @NoArgsConstructor public class Dog { @Value("毛豆") private String name; @Value("3") private Integer age; }
-
在SpringBoot的测试类下注入Dog类输出一下
import com.pan.entity.Dog; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class SpringBoot01ApplicationTests { @Autowired // 将Dog类自动注入进来 Dog dog; @Test void contextLoads() { System.out.println(dog); //打印Dog类对象 } }
-
成功输出结果:
2.@ConfigurationProperties
@ConfigurationProperties与上面的区别就是没有直接用@value,而是通过一个注解类,最后引用的是对象而不是所属值。通过对象注解,引用核心配置文件@ConfigurationProperties
主要是为了映射对象,@Component
将此类将给spring容器进行管理。
首先引入依赖:
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
现在我们编写一个复杂的实体类 Human类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component //注册bean到容器中
@Data //有参无参构造、get、set方法、toString()方法
@AllArgsConstructor
@NoArgsConstructor
public class Human {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
我们来使用yaml配置的方式进行注入
human:
name: tom
age: 3
happy: false
birth: 2023/01/01
maps: {k1: v1,k2: v2}
lists:
- code
- book
- music
dog:
name: 毛豆
age: 1
我们刚才已经把human这个对象的所有值都写好了,我们现在来注入到我们的类中
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “human” : 将配置文件中的human下面的所有属性一一对应
*/
@Component //注册bean到容器中
@Data //有参无参构造、get、set方法、toString()方法
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "human")
public class Human {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
去测试类测试:
@SpringBootTest
class SpringBoot01ApplicationTests {
@Autowired // 将Human类自动注入进来
Human human;
@Test
void contextLoads() {
System.out.println(human); //打印Human类对象
}
}
测试成功:
加载指定的配置文件
**@PropertySource :**加载指定的配置文件;
@configurationProperties:默认从全局配置文件中获取值;
1、我们去在resources目录下新建一个human.yaml文件
name:
tom
2、然后在我们的代码中指定加载person.properties文件
@PropertySource(value = "classpath:human.yaml")
@Component //注册bean
public class Human {
@Value("${name}")
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
3、输出结果
Human(name=tom, age=null, happy=null, birth=null, maps=null, lists=null, dog=null)
配置文件占位符
配置文件还可以编写占位符生成随机数
human:
name: tom${random.uuid} # 随机uuid
age: ${random.int} # 随机int
happy: false
birth: 2023/01/01
maps: {k1: v1,k2: v2}
lists:
- code
- book
- music
dog:
name: 旺财
age: 1