一、配置文件
SpringBoot使用一個文件名固定的全局配置文件:
application.properties
application.yml
配置文件放在 src/main/resources 目錄或者 src/main/resources/config 下
配置文件的作用:修改SpringBoot自動配置的默認值,這些默認值都是Spring在底層自動配置好的;
yml是YAML語言的文件,特點是以數據爲中心,相對 xml 配置文件,yml寫法相對較簡介
yml語法參考: https://yaml.org/
標記語言:
以前使用Spring框架的時候,配置文件大多是 xxxx.xml 文件,xml即是一種標記語言
YML配置例子:
server:
port: 8080
XML配置例子:
<server>
<port>8080</port>
</server>
二、YML語法
1、基本語法
k:(空格)v 表示一對鍵值對(空格必須有)
以空格的縮進來控制層級關係;只要是左對齊的一列數據,都是同一個層級的
server:
port: 8080
path: /hello
屬性和值都是大小寫敏感;
2、值的寫法
- 字面量:普通的值(字符串、數字、布爾值、日期)
k: v 字面量的值直接寫
字符串默認不用加單引號或雙引號;
"":雙引號,不會轉義字符串裏面的特殊字符,例:
name: "zhangsan \n lisi" 輸出: zhangsan 換行 lisi
'':單引號,會轉義特殊字符,例:
name: "zhangsan \n lisi" 輸出: zhangsan \n lisi
- Map對象
k: v 下一行寫對象的屬性和值,注意縮進;
對象還是k: v的方式
student:
name: zhangsan
age: 20
行內寫法:
student: {name: zhangsan,age: 20}
- 數組(List,Set)
用 - 表示數組中的一個元素
pets:
- dog
- cat
- pig
行內寫法:
pets: [dog,cat,pig]
三、配置文件注入
person:
name: zhangsan
age: 20
boss: false
birth: 2011/10/11
maps: {k1: v1,k2: v2}
lists:
- lisi
- wangwu
dog:
name: 小狗
age: 2
Java Bean 的寫法:
/**
* 將配置文件中配置的每一個屬性的值,映射到這個Compenent中
* @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置文件中相關的配置進行綁定
* prefix = "person":配置文件中person下面的所有屬性都一一映射
* 只有這個組價是容器中的組件,才能使用容器提供的 @ConfigurationProperties 功能
*/
@Component
@ConfigurationProperties(prefix = "person")
@Data
@ToString
public class Person{
private String name;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
}
可以通過引入配置文件處理器,來實現配置文件編寫提示功能
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Value 註解
該註解等同於Spring舊版本的xml配置文件中的 property 標籤
/**
* 將配置文件中配置的每一個屬性的值,映射到這個Compenent中
*/
@Component
@Data
@ToString
public class Person{
/**
* <bean class = "Person">
* <property name = "name" value = "zhangsan"></property>
* </bean>
*
*/
@Value("zhangsan")
private String name;
}
@Value註解的取值可以有以下幾種形式:
字面量: @Value("zhangsan")
${key} 從環境變量或配置文件中取值
#{SpEL} 使用SpEL表達式取值
@Value("${person.name}")
private String name;
@Value("#{11*2}")
private Integer age;
@Value("true")
private Boolean boss;
@ConfigurationProperties 註解
- 與@Bean結合爲屬性賦值
- 與@PropertySource (只能用於properteis文件)結合讀取指定文件
四、@Value 獲取值和 @ConfigurationProperties 獲取值的比較
@ConfigurationProperties | @Value | |
功能 | 批量注入文件屬性 | 單個注入 |
鬆散綁定(鬆散語法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303數據校驗 | 支持 |
不支持 |
複雜類型封裝 | 支持 | 不支持 |
配置文件yml和properties都可以通過這兩種註解取值
如果是某個業務邏輯中需要獲取配置文件中的某項值,建議用 @Value
如果是專門寫了JavaBean來和配置文件映射,建議用 @ConfigurationProperties
注意:兩種註解不能在同一個Bean中同時使用
JSR數據校驗舉例:
/**
* 將配置文件中配置的每一個屬性的值,映射到這個Compenent中
* @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置文件中相關的配置進行綁定
* prefix = "person":配置文件中person下面的所有屬性都一一映射
* 只有這個組價是容器中的組件,才能使用容器提供的 @ConfigurationProperties 功能
* 默認從全局配置文件中取值
*/
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person{
// 不能爲空
@NotNull
private String name;
// 必須是郵箱格式
@Email
private String email;
}
五、@PropertySource與@ImportSource
@PropertySource:讀取指定的配置文件
示例:
1、在src/main/resources 目錄下 創建一個person.properties文件
person.name=zhangsan
person.age=18
2、JavaBean中通過@PropertySource獲取配置文件的屬性值
/**
* 將配置文件中配置的每一個屬性的值,映射到這個Compenent中
* @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置文件中相關的配置進行綁定
* prefix = "person":配置文件中person下面的所有屬性都一一映射
* 只有這個組價是容器中的組件,才能使用容器提供的 @ConfigurationProperties 功能
*/
@PropertySource(value = "classpath:person.properties")
@Component
@ConfigurationProperties(prefix = "person")
public class Person{
private String name;
private Integer age;
}
3、測試驗證
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
Person person;
@Test
public void test() {
System.out.println(person);
}
}
控制打印輸出Person
Person{name='zhangsan',age=18}
@ImportResource:導入Spring配置文件,讓配置文件中的內容生效
示例:
1、創建一個HelloService類
public class HelloService {
}
2、在 src/main/resource 目錄中創建一個bean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "helloService" class = "com.xxx.xxx.HelloService"></bean>
</beans>
3、SpringBoot主配置類使用 @ImportResource 注入 bean.xml ,也是標註在其他的SpringBoot配置類
@ImportResource(locations = "classpath:bean.xml")
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
4、驗證測試 HelloService 是否注入到SpringBoot容器中
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
ApplicationContext ioc;
@Test
public void contextLoads() {
boolean b = ioc.containsBean("helloService");
System.out.println(b);
}
}
控制檯輸出 true ,注入成功
上面的方法還是過於繁瑣了些,SpringBoot有更好的給容器添加組件的方式:全註解方式
使用 @Configuration 和 @Bean 給SpringBoot容器注入 組件
1、創建一個java類,使用 @Configuration ,表明這是一個SpringBoot的配置類,使用 @Bean ,將方法的返回值作爲組件注入容器
/**
* @Configuration 指明當前是一個配置類,提到Spring的配置文件
*
*/
@Configuration
public class MyAppConfig {
// 將方法的返回值添加到容器中,容器中這個組件的默認ID就是方法名
@Bean
public HelloService helloService {
return new HelloService();
}
}
2、驗證測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
ApplicationContext ioc;
@Test
public void contextLoads() {
boolean b = ioc.containsBean("helloService");
System.out.println(b);
}
}
控制檯輸出 true ,注入成功
六、配置文件的佔位符
佔位符的取值:
- 可以是隨機數
${random.value}
${random.int}
${random.int(10)}
${random.int[1024,65536]}
${random.long}
- 也可以是配置文件中前面配置過的屬性
app.name=MyApp
app.desc=${app.name} is a SpringBoot Application
${app.name:默認值}用來指定找不打屬性時的默認值
七、SpringBoot的profile
Profile是Spring對不同環境提供不同配置功能的支持,可以通過激活、指定配置等方式快速切換環境
1、多profile文件形式:
格式: application-{profile}.properties
例: application-dev.properties、application-prod.properties
2、激活方式:
- 命令行: --spring.profiles.active=dev
- 配置文件: spring.profiles.active=dev
- JVM啓動參數:-Dspring.profiles.active=dev
激活方式優先級: JVM啓動參數& 命令行 > 配置文件
命令行啓動的時候加入參數 java -jar xxxxx.jar --spring.profiles.active=dev ,或者如下設置:
JVM啓動參數的設置如下:
-D 開頭爲虛擬機參數的固定寫法
yml支持多文檔模式
例:在application.yml配置文件中配置如下
server:
port: 8080
spring:
profiles:
active: dev
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: prod
啓動的端口爲 8081
八、配置文件加載順序
SpringBoot啓動會掃描以下位置的application.properties或者application.yml文件作爲SpringBoot的默認配置文件。
-file:./config/
-file:./
-classpath:/config/
-classpath:/
優先級從高到低,高優先級的配置會覆蓋低優先級的配置;
SpringBoot會從這四個位置加載全部的配置文件(如果有的話),並且這些配置有互補效應;
我們還可以通過 spring.config.location 來改變默認的配置文件位置
在不改變項目代碼所在jar包的情況下,啓動的時候加上 spring.config.location 參數來加載指定位置的application.properties配置文件;
例:
java -jar xxxx.jar --spring.config.location=/home/xxx/application.properties
參數指定的配置文件與其他方式加載的配置文件共同起作用,且與其他配件文件一起有互補效應;
九、外部配置加載順序
SpringBoot也可以從以下位置加載配置值:優先級從高到低,高優先級的配置覆蓋低優先級的配置,所有配置形成互補效應;
1、命令行參數
java -jar xxxxx.jar --server.port=8087 --server.context-path=/abc
多配置用空格分開; --配置項=值
2、來自java:comp/env 的JNDI屬性
3、Java系統屬性(System.getProperties())
4、操作系統環境變量
5、RandomValuePropertiesSource配置的 random.* 屬性值
由jar包外向jar包內尋找;
優先加載帶 profile
6、jar包外部的 application-{profile}.properties 或 application.yml(帶sping-profile)配置文件
7、jar包內部的 application-{profile}.properties 或 application.yml(帶sping-profile)配置文件
再來加載不帶profile
8、jar包外部的 application.properties 或 application.yml(不帶sping-profile)配置文件
9、jar包內部的 application.properties 或 application.yml(不帶sping-profile)配置文件
10、@Configuration註解類上的@PropertySource
11、通過SpringApplication.setDefaultProperties指定的默認屬性
所有支持的配置加載來源(官網文檔):
教程視頻來源: