SpringBoot專題(二):配置

一、配置文件

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指定的默認屬性

所有支持的配置加載來源(官網文檔):

https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/htmlsingle/#boot-features-external-config


教程視頻來源:

尚硅谷_SpringBoot核心技術

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章