1. 程式人生 > >第三章spring boot原理分析

第三章spring boot原理分析

圖片 tom 應用 adf cati att nat sse 自動配置

1、分析spring-boot-starter-parent

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
    </parent>
他的父項目
<parent>
<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他來真正管理Spring Boot應用裏面的所有依賴版本;

按照Ctrl點擊pom.xml中的spring-boot-starter-dependencies,跳轉到了spring-boot-starter-dependencies

pom.xmlxml配置如下(只摘抄了部分重點配置):

從上面的spring-boot-starter-dependenciespom.xml中可以發現,一部分坐標的版本、依賴管理、插件管理已經定義好,所以SpringBoot工程繼承spring-boot-starter-parent後已經具備版本鎖定等配置了。所以起步依賴的作用就是進行依賴的傳遞。後我們導入依賴默認是不需要寫版本;(沒有在dependencies裏面管理的依賴自然需要聲明版本號)

2、分析spring-boot-starter-web啟動器

  <dependency>
      <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

spring-boot-starter-web:
spring-boot-starter:spring-boot場景啟動器;幫我們導入了web模塊正常運行所依賴的組件;
Spring Boot將所有的功能場景都抽取出來,做成一個個的starters(啟動器),只需要在項目裏面引入這些starter
相關場景的所有依賴都會導入進來。要用什麽功能就導入什麽場景的啟動器

3、主程序類,主入口類

/**
 * @SpringBootApplication 來標註一個主程序類,說明這是一個Spring Boot應用
 */
@SpringBootApplication
public class HellStartMain {
    public static void main(String[] args) {
        //spring啟動起來
        SpringApplication.run(HellStartMain.class);
    }
}

1、@SpringBootApplication

Spring Boot應用標註在某個類上說明這個類是SpringBoot的主配置類,SpringBoot
就應該運行這個類的main方法來啟動SpringBoot應用;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication

2、@SpringBootConfiguration

SpringBoot的配置類,標註這個類,表明SpringBoot是一個配置類

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration{
@Configuration:配置類上面標註這個註解
配置類---配置文件;配置也是一個組件;@Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

3、@EnableAutoConfiguration

 開啟自動配置功能;以前需要配置的東西,Spring Boot幫我們自動配置;@EnableAutoConfiguration告訴SpringBoot開啟自動配置功能;這樣自動配置才能生效;
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
AutoConfigurationPackage:自動導入包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

Spring的底層註解@Import,給容器中導入一個組件;導入的組件由AutoConfigurationPackages.Registrar.class;
將主配置類(@SpringBootApplication標註的類)的所在包及下面所有子包裏面的所有組件掃描到Spring容器;
@Import(AutoConfigurationImportSelector.class)給容器導入組件
public class AutoConfigurationImportSelector{
   public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        configurations = this.removeDuplicates(configurations);
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        this.checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = this.filter(configurations, autoConfigurationMetadata);
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
    }
}
}

EnableAutoConfigurationImportSelector:導入哪些組件的選擇器;
將所有需要導入的組件以全類名的方式返回;這些組件就會被添加到容器中;
會給容器中導入非常多的自動配置類(xxxAutoConfiguration);就是給容器中導入這個場景需要的所有組件,
並配置好這些組件;有了自動配置類,免去了我們手動編寫配置註入功能組件等的工作;

? SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);

Spring Boot在啟動的時候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,將這些值作為自動配置類導入到容器中,

自動配置類就生效,幫我們進行自動配置工作;以前我們需要自己配置的東西,自動配置類都幫我們;

其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是掃描所有jar包類路徑下 META-INF/spring.factories文件中讀取指定類對應的類名稱列表,把掃描到的這些文件的內容包裝成properties對象

從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,然後把他們添加在容器中

技術分享圖片

spring.factories 文件中有關自動配置的配置信息如下:

技術分享圖片

J2EE的整體整合解決方案和自動配置都在spring-boot-autoconfigure-2.0.6.RELEASE.jar;


第三章spring boot原理分析