基本概念
- SpringBoot的優點:
- 可以建立獨立的Spring應用
- SpringBoot嵌入Tomcat,Jetty和Unsertow, 不需要部署war檔案
- 根據需要通過maven獲取starter
- 對Spring進行自動配置
- 提供生產就緒型功能,包括指標,健康檢查和外部配置
SpringBoot父專案
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
- 管理SpringBoot應用裡面所有的依賴版本,這樣以後匯入依賴預設不需要寫版本號,可以統一管理開發版本(沒有在dependencies裡面管理的依賴才需要宣告版本號)
spring-boot-starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- spring-boot-starter: springboot場景啟動器
- spring-boot-starter-web: 匯入web模組正常執行所依賴的元件
- SpringBoot將所有的功能場景都抽取出來,做成各個starter啟動器,只需要在專案的pom.xml中引入這些starter依賴,相關場景的所有依賴都會被匯入進來。
@SpringBootApplication
- @SpringBootApplication:標註在SpringBoot的主配置類,SpringBoot就會執行這個類的main方法來啟動SpringBoot運用。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //SpringBoot配置類,類似於配置檔案。配置類也是容器中的元件。標註在類上標明是一個SpringBoot配置類
@EnableAutoConfiguration //開啟SpringBoot自動配置功能
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "exclude"
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "excludeName"
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}
- @SpringBootConfiguration: SpringBoot配置類,類似於配置檔案。配置類也是容器中的元件。標註在類上標明是一個SpringBoot配置類
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 表明該類是一個Spring的配置類
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 表明該類是Spring的一個元件
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value default "";
boolean proxyBeanMethods() default true;
}
- @EnableAutoConfiguration: 開啟SpringBoot自動配置功能
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
- @AutoConfigurationPackage: 自動配置包,通過 @Import({Registrar.class}) 完成,通過檢視Registrar原始碼發現將主配置類即 @SpringBootApplication標註的類的所在包及所有子包裡面的所有元件掃描到Spring容器中
- 其中,@Import是Spring的底層註解,給容器匯入一個元件,匯入的元件由Registrar.class來指定。
- AutoConfigurationImportSelector:匯入元件的選擇器,將所有需要匯入的元件以全類名的方式返回,這樣元件就會被新增到容器中
- 會給容器中匯入自動配置類:就是給容器中匯入場景所有的元件並配置好.這樣就不用手動編寫配置並注入功能元件
- SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader):
- 從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值
- 過程總結:
- SpringBoot在啟動的時候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值
- 將這些值作為自動配置類匯入到容器中,自動配置類就會生效,進行配置工作。
- J2EE的整體整合解決方案和自動配置都在spring-boot-autoconfigure-2.0.1.RELEASE.jar中
在SpringBoot專案中的resources資料夾:
- static:儲存所有靜態資源,例如 js,css,images
- templates:儲存所有的模板頁面。在SpringBoot中預設jar包使用的是嵌入式tomcat,預設不支援jsp頁面。可以使用模板引擎:freemarker,thymeleaf
- application.properties:SpringBoot應用的配置檔案,可以修改一些預設設定
SpringBoot配置
配置檔案
SpringBoot使用一個全域性配置檔案,配置檔名是固定的:
- application.properties
- application.yml
- 配置檔案作用:修改SpringBoot自動配置的預設值。
yml
- yml:(YAML Ain't Markup Language)以資料為中心,比json、xml等更適合做配置檔案。
YAML基本語法
- key: value(表示一對鍵值對。value前面必須要有空格。)
- 以空格縮排來表示層級關係,只要是左對齊的一列資料,都是同一個層級的
1.縮排時不允許使用Tab鍵,只允許使用空格
2.縮排的空格數目不重要,只要相同層級的元素左側對齊即可 - 屬性和值是大小寫敏感
- 值的寫法:
- 字面量:普通的值(數字,字串,布林值)
- key:value :字面量直接書寫。字串預設不加引號。
- 單引號-轉義字元會作為普通字串輸出
- 雙引號-轉義字元會轉變成格式
- 物件、Map(屬性和值,鍵值對):
- 物件還是key: value的方式
friends:
lastName: Chova
firstName: Vea
行內寫法:
friends: {lastName: Chova,firstName: Vea}
- 陣列(List、Set)
- 用 - 值表示陣列中的元素
pets:
- dog
- cat
- pig
行內寫法:
pets: [dog,cat,pig]
@Value獲取值和@ConfigurationProperties獲取值比較
@Value | @ConfigurationProperties | |
---|---|---|
功能 | 在屬性上一個一個指定注入 | 批量注入配置檔案中的屬性 |
鬆散繫結(鬆散語法) | 不支援 | 支援 |
SpEL | 支援 | 不支援 |
JSR303資料校驗 | 不支援 | 支援 |
複雜型別封裝 | 不支援 | 支援 |
- 如果我們只是在某個業務邏輯中需要獲取一下配置檔案的某項值,就使用@Value
- 如果JavaBean需要和配置檔案進行對映,就使用@ConfigurationProperties
配置檔案注入值數值校驗(JSR303)
- 必須要用 @ConfigurationProperties
- JSR303資料校驗:@Validate-@Email
@PropertySource和@ImportResource
- @PropertySource:載入指定的配置檔案
@PropertySource(value = {"classpath:person.properties"})
- @ImportResource:匯入Spring的配置檔案,讓配置檔案的內容生效
@ImportResource(locations={"classpath:beans.xml"})
- SpringBoot推薦給容器中新增元件的方式: 推薦使用 全註解 的方式
1.配置類 --- Spring配置檔案
2.使用 @Bean在配置類中為容器中新增元件
配置檔案佔位符
- RandomValuePropertySource:配置檔案中可以使用隨機數
1.${random.value}
2.${random.int}
3.${random.int(10)}
4.${random.int[1024,65536]}
- 屬性配置佔位符:
1.可以在配置檔案中引用前面配置過的屬性(優先順序前面配置過的這裡都能用)
2.${app.name:預設值}來指定找不到屬性值時的預設值
Profile
- 多Profile檔案:
1.在寫配置檔案的時候,檔名可以是:application-{profile}.properties/yml
2.預設使用application.properties的配置 - yml支援多文件塊方式
- 用"- - -"劃分文件塊
---
啟用指定Profile:
1.在主配置檔案application.properties中指定啟用:
spring.profiles.active=dev
2.命令列啟用:(Program arguments)
--spring.profiles.active=dev
3.虛擬機器引數啟用:(VM options)
-Dspring.profiles.active=dev
配置檔案載入位置
- SpringBoot啟動會掃描以下位置的application.properties或者application.yml檔案作為SpringBoot的預設配置檔案
- file:./config/
- file:./
- classpath:/config
- classpath:/
- 以上按照優先順序從高到低,所有檔案都會被載入,互補配置。高優先順序內容會覆蓋低優先順序內容。
- 可以通過配置- -spring.config.location來改變預設配置位置:專案打包好以後,使用命令列引數的形式,啟動專案的時候來指定配置檔案的新位置,指定的配置檔案和預設載入的配置檔案會共同起作用,互補配置。
外部配置的載入順序
- SpringBoot支援多種外部配置方式,優先順序如下:
1.命令列引數(- -,多個命令用空格分開)
2.來自java:comp/env的JNDI屬性
3.Java系統屬性(System.getProperties())
4.作業系統環境變數
5.RandomValuePropertySource配置的random.*屬性值
由jar包外部向jar包內進行尋找:
優先載入帶profile的:
6.jar包外部的application-{profile}.properties/yml(帶spring.profile)配置檔案
7.jar包內部的application-{profile}.properties/yml(帶spring.profile)配置檔案
然後載入不帶Profile的:
8.jar包外部的application-{profile}.properties/yml(不帶spring.profile)配置檔案
9.jar包內部的application-{profile}.properties/yml(不帶spring.profile)配置檔案
10.@Configuration註解類上的@PropertySource
11.通過SpringApplication.setDefaultProperties指定的預設屬性
自動配置原理
- SpringBoot啟動時載入主配置類,開啟了自動配置功能 @EnableAutoConfiguration
- @EnableAutoConfiguration作用:利用EnableAutoConfigurationImportSelector給容器匯入元件。
具體實現可以檢視selectImports() 方法:
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);獲取候選的配置
SpringFactoriesLoader.loadFactoryNames();掃描所有jar包類路徑下:META-INF/spring.factories。把掃描到的這些檔案的內容包裝成properties物件,從properties中獲取到EnableAutoConfiguration.class(類名)類的值,然後把它們新增在容器中
將類路徑下META-INF/spring.factories裡面配置的所有EnableAutoConfiguration的值加入到了容器中。
- 每一個自動配置類進行自動配置功能。
@Configuration // 表示這是一個配置類,類似配置檔案,可以給容器中新增元件
@EnableConfigurationProperties({HttpProperties.class}) // 啟用指定類的ConfigurationProperties(從配置檔案中獲取指定的值和bean的屬性進行繫結)功能
@ConditionalOnWebApplication( // Spring底層@conditional註解,根據不同的條件,如果滿足指定的條件,整個配置類裡面的配置就會生效(判斷當前應用是否為web應用)
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class}) // 判斷當前專案有沒有這個類,CharacterEncodingFilter:SpringMVC中進行亂碼解決的過濾器
@ConditionalOnProperty( // 判斷檔案中是否存在某個配置
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true // 即使配置檔案中不配置spring.http.encoding.enable=true,也是預設生效的
)
public class HttpEncodingAutoConfiguration {
根據當前不同的條件判斷,決定配置類是否生效,就會通過@Bean為容器中新增各種元件,這些元件的值需要從properties中獲取,properties中的每一個屬性和配置檔案繫結。
注意點:
- @Conditional派生註解(來源於Spring底層註解@Conditional)
1.作用:必須是@Conditional指定的條件成立,才給容器中新增元件,配置裡面的所有內容才生效。
2.自動配置類必須在一定的條件下才會生效:在配置檔案中
debug=true
可以在控制檯列印自動配置報告,可以檢視哪些自動配置生效,哪些自動配置不生效。
總結
- SpringBoot啟動會載入大量的自動配置類。
- 判斷SpringBoot預設寫好的自動配置類有沒有需要的功能。
- 判斷自動配置類是否配置需要的元件,沒有的就需要自己配置。
- 給容器中自動配置類新增元件時,會從properties中獲取屬性,在配置檔案中指定這些屬性的值。
- xxAutoConfiguration:自動配置類,給容器中新增元件===xxProperties:封裝配置檔案中的相關屬性,和配置檔案繫結