微服務架構學習Day01-SpringBoot入門

攻城獅Chova發表於2021-02-10

基本概念

  • SpringBoot的優點:
    • 可以建立獨立的Spring應用
    • SpringBoot嵌入Tomcat,JettyUnsertow, 不需要部署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的預設配置檔案
  1. file:./config/
  2. file:./
  3. classpath:/config
  4. 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:封裝配置檔案中的相關屬性,和配置檔案繫結

相關文章