SpringBoot學習筆記-SpringBoot配置
阿新 • • 發佈:2018-11-24
SpringBoot學習筆記-SpringBoot配置
Table of Contents
- 1. Spring Boot配置
1 Spring Boot配置
1.1 配置檔案
- SpringBoot使用一個全域性的配置檔案
application.properties
application.yml
: YAML(YAML Ain't Markup Language), 以資料為中心, 比json, xml更適合做配置檔案.
server: port: 8081
- 配置檔案的作用: 修改SpringBoot自動配置的預設值.
1.2 YAML語法
- 使用縮排表示層級關係.
- 縮排時不允許使用Tab鍵,只允許使用空格.
- 縮排空格數目不重要,只要相同層級的元素左側對齊即可
- 大小寫敏感
1.3 YAML的資料結構
- 物件: 鍵值對的集合.
- 陣列: 一組按次序排列的值.
- 字面量: 單個的,不可再分的值.
1.3.1 字面量
- 字面量的字串預設不用加上單引號或者雙引號.
""
雙引號, 不會轉移字串裡面的特殊字元.- "zhangsan\nlisi" -> zhangsan換行lisi
''
單引號, 會轉義特殊字元, 特殊字元最終只是一個普通的字串資料.- "zhangsan\nlisi" -> zhangsan\nlisi
K: V: 字面量
1.3.2 物件
- 物件的語法是物件加屬性的kv形式.
friends: lastName: zhangsan age: 20
- 行內寫法
friends: {lastName: zhangsan, age: 18}
1.3.3 陣列(List,Set)
- 用
-值
來表示陣列的一個元素.
pets:
- cat
- dog
- pig
- 行內寫法
pets: [cat,dog,pig]
1.4 獲取yaml配置檔案值注入
- yaml配置檔案
person: lastName: zhangsan age: 18 boss: false birth: 2017/12/12 maps: {k1: v1, k2: 12} lists: - lisi - zhaoliu dog: name: 小狗 age: 2
- 元件bean
package com.devinkin.springboot.bean; 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", 配置檔案中哪個下面的所有屬性進行一一對映 * * @Component 只有這個元件是容器中的元件,才能使用容器提供@ConfigurationProperties的功能. */ @Component @ConfigurationProperties(prefix = "person") public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Map<String, Object> maps; private List<Object> lists; public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Boolean getBoss() { return boss; } public void setBoss(Boolean boss) { this.boss = boss; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } @Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps=" + maps + ", lists=" + lists + '}'; } }
- 匯入配置檔案處理器,以後編寫配置就有提示了
<!-- 匯入配置檔案處理器, 配置檔案進行繫結就會有提示 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
- 如果從properties配置檔案中獲取值注入,idea需要注意一下設定.
- 因為properties預設編碼是ascii,而idea預設編碼是utf-8
1.5 @Value獲取值和@ConfigurationProperties獲取值的比較
- 配置檔案無論是yaml還是properties都能獲取到值.
- 如果說我們只是在某個業務邏輯中需要獲取一項配置檔案的某項值,我們就使用
@Value
- 如果我們專門編寫了一個javaBean來和配置檔案進行校驗,我們就直接使用
@ConfigurationProperties
@ConfigurationProperties | @Value | |
功能 | 批量注入配置檔案的屬性 | 一個個指定 |
鬆散繫結(鬆散語法) | 支援 | 不支援 |
SpEL | 不支援 | 支援 |
JSR303資料校驗 | 支援 | 不支援 |
複雜型別封裝 | 支援 | 不支援 |
1.6 配置檔案注入值資料校驗
- 使用
@Validated
註解.
@Component @ConfigurationProperties(prefix = "person") @Validated public class Person { /** * <bean class="Person"> * <property name="lastName" value="字面量"/${key}從環境變數,配置檔案中獲取值/#{SpEL}></property> * </bean> */ // @Value("${person.last-name}") // LastName必須是有效的格式 @Email private String lastName; }
1.7 @PropertySource和@ImportResource
@PropertySource
載入指定的配置檔案- 例:
@PropertySource(value = {"classpath:person.properties"})
@ImportResource
匯入Spring的配置檔案, 讓配置檔案裡面的內容生效.- SpringBoot裡面沒有Spring的配置檔案,我們自己編寫的配置檔案,也不能自動識別.
- 想讓Spring的配置檔案載入進來, 把
@ImportResource
標註在主配置類上.
@ImportResource(locations = {"classpath:beans.xml"}) @SpringBootApplication public class SpringBoot02ConfigApplication { public static void main(String[] args) { SpringApplication.run(SpringBoot02ConfigApplication.class, args); } }
- SpringBoot推薦給容器中新增元件的方式: 使用全註解的方式.
- 使用
@Bean
給容器中新增元件
- 使用
package com.devinkin.springboot.config; import com.devinkin.springboot.service.HelloService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Configuration 它指明當前類是一個配置類,就是來替代之前的Spring配置檔案 */ @Configuration public class MyAppConfig { /** * 將方法的返回值新增到容器中: 容器中這個元件預設的id就是方法名 * @return */ @Bean public HelloService helloService() { System.out.println("配置類@Bean給容器中新增元件了..."); return new HelloService(); } }
1.8 配置檔案的佔位符
- RandomValuePropertySource: 配置檔案中可以使用隨機數
${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int(1024,65536)}
- 屬性配置佔位符
- 可以在配置檔案中引入前面配置過的屬性(優先順序前面配置過的這裡都能用).
$app.name:預設值$
來指定找不到屬性時的預設值.
# idea使用的是utf-8 # 配置person的值 person.last-name=張三${random.uuid} person.age=${random.int} person.birth=2019/02/01 person.boss=false person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=${person.last-name}_habi person.dog.age=15
1.9 Profile
- Profile是Spring對不同環境提供不同配置功能的支援,可以通過啟用,指定引數等方式快速切換環境.
- 多profile檔案形式
- 格式:
application-{profile}.properties/yaml
- 格式:
- yaml多profile文件模式,
profiles
用於區分不同的文件.- 使用
---
分割多文件塊.
- 使用
server: port: 8081 spring: profiles: active: dev --- server: port: 8082 spring: profiles: prod --- server: port: 8083 spring: profiles: dev ---
- 啟用profile的方式
- 命令列:
--spring.profiles.active=dev
- 配置檔案:
spring.profiles.active=dev
- jvm引數:
-Dspring.profiles.active=dev
- 命令列:
1.10 配置檔案的載入位置
- SpringBoot啟動會掃描一下位置下的
application.properties
或者application.yml
檔案作為SpringBoot的預設配置檔案.- 優先順序從高到低的順序,所有位置的檔案都會被載入,高優先順序配置內容會覆蓋低優先順序配置內容.
./config/
./
classpath:/config/
classpath:/
- SpringBoot會從這四個位置載入主配置檔案: 互補配置.
- SpringBoot2.x棄用了
server.context-path
, 改用server.servlet.context-path
- SpringBoot2.x棄用了
- 可以配置
spring.config.location
來改變預設配置. 不過在專案除錯的時候不會使用該配置.- 專案打包以後,我們可以使用命令列引數的形式,在專案啟動的時候來指定配置檔案的新位置.
- 指定的配置檔案和預設載入的這些配置檔案共同起作用, 互補配置.
1.11 外部配置載入順序
- SpringBoot也可以從以下位置載入配置,優先順序從高到低,高優先順序的配置覆蓋低優先順序的配置,所有的配置會形成互補的配置.
- 命令列引數.
- 來自
java:comp/env
的JNDI
屬性. - Java系統屬性
System.getProperties()
- 作業系統環境變數.
- RandomValuePropertySource配置的
random.*
屬性值. - jar包外部的
application-{profile}.properties
或application.yml
(帶spring.profile) 配置檔案 - jar包內部的
application-{profile}.properties
或application.yml
(帶spring.profile) 配置檔案 - jar包外部的
application-{profile}.properties
或application.yml
(不帶spring.profile) 配置檔案 - jar包內部的
application-{profile}.properties
或application.yml
(不帶spring.profile) 配置檔案 @Configuration
註解類上的@PropertySource
- 通過
SpringApplication.setDefaultProperties
指定的預設屬性.
1.12 自動配置原理
- SpringBoot啟動的時候載入主配置類,開啟了自動配置功能
@EnableAutoConfiguration
@EnableAutoConfiguration
作用: 將類路徑下的META-INF/spring.factories
裡面配置的所有EnableAutoConfiguration
的值加到了容器中.- 利用
EnableAutoConfigurationImportSelector
給容器匯入一些元件. - 檢視
EnableAutoConfigurationImportSelector
其父類的selectImports
方法. List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);
獲取候選的配置.SpringFactoriesLoader.loadFactoryNames()
掃描所有jar包類路徑下的META-INF/spring.factories
- 把掃描到的這些檔案的內容包裝成
Properties
物件 - 從
Properties
中獲取到EnableAutoConfiguration.class
類(類名)對應的值,然後把它們新增到容器中.
- 利用
- 每一個自動配置類進行自動配置功能.
- 以
HttpEncodingAutoConfiguration
為例解釋自動配置原理.- 根據當前不同的條件判斷,決定這個配置類是否生效.
@Configuration // 啟動指定類的ConfigurationProperties功能 // 將配置檔案中對應的值和HttpEncodingProperties繫結起來.並把 HttpEncodingProperties 加入到IOC容器中. @EnableConfigurationProperties(HttpEncodingProperties.class) // Spring底層@Conditional註解,根據不同得到條件,如果滿足指定的條件,整個配置類裡面的配置就會生效. // 判斷當前應用是否為Web應用 @ConditionalOnWebApplication // 判斷當前專案有沒有CharacterFilter類(SpringMVC進行亂碼解決的過濾器) @ConditionalOnClass(CharacterEncodingFilter.class) // 判斷配置檔案中是否存在某個配置 spring.http.encoding.enabled, 如果不存在, 判斷也是成立的. // 即使配置檔案中不配置 spring.http.encoding.enabled, 也是預設生效的. @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration {}
- 所有在配置檔案中配置的屬性都是在
xxxProperties
類中封裝著, 配置檔案能配置什麼就可以參照某個功能對應的這個屬性類.
// 從配置檔案中獲取指定的值和bean的屬性進行繫結. @ConfigurationProperties(prefix = "spring.http.encoding") public class HttpEncodingProperties {}
- 給容器中新增一個元件, 這個元件的某些值需要從properties中獲取.
@Bean @ConditionalOnMissingBean(CharacterEncodingFilter.class) public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }
1.13 SpringBoot精髓
- SpringBoot啟動會載入大量的自動配置類
- 看SpringBoot預設寫好的自動配置類有沒有我們需要的功能.
- 我們再來看自動配置類中到底配置了哪些元件.(只要我們使用的元件有,我們就不需要再來配置).
- 給容器中自動配置類新增元件的時候,會從
Properties
類中獲取某些屬性, 我們就可以在配置檔案中指定這些屬性的值.
1.14 @Condition派生註解
@Condition
作用: 指定的條件成立, 才給容器中新增元件, 配置類裡面的所有內容才生效.- Condition註解的擴充套件
@Condition擴充套件註解 | 作用(判斷是否滿足當前指定條件) |
@ConditionOnJava | 系統的Java版本是否符合要求 |
@ConditionOnBean | 容器中存在指定Bean |
@ConditionOnMissingBean | 容器中不存在指定Bean |
@ConditionOnExpression | 滿足SpEL表示式指定 |
@ConditionOnClass | 系統中有指定的類 |
@ConditionOnMissingClass | 系統中沒有指定的類 |
@ConditionOnSingleCandidate | 容器中只有一個指定的Bean,或者這個Bean是首選Bean |
@ConditionOnProperty | 系統中指定的屬性是否有指定的值 |
@ConditionOnResource | 類路徑下是否存在指定資原始檔 |
@ConditionOnWebApplication | 類路徑下是否存在指定資原始檔 |
- 在配置檔案中新增如下配置
debug=true
啟用debug模式, 可以檢視載入了哪些自動配置類.
Date: 2018-11-20 20:15
Created: 2018-11-24 六 19:48