天天看點

SpringBoot(三)

1.POM檔案解析

1.1父項目

SpringBoot(三)

項目需要依賴的父項目【spring‐boot‐starter‐parent】

SpringBoot(三)

【spring‐boot‐starter‐parent】依賴于【 spring-boot-dependencies】

<!-- 存放項目需要的所有依賴 -->
<properties>
    <activemq.version>5.16.4</activemq.version>
    <antlr2.version>2.7.7</antlr2.version>
    <appengine-sdk.version>1.9.95</appengine-sdk.version>
    <artemis.version>2.19.1</artemis.version>
    <aspectj.version>1.9.7</aspectj.version>
    <assertj.version>3.21.0</assertj.version>
    ......
<properties>


<!-- 上面的<properties>元素中配置的是我們所建立的項目的所有依賴包版本-->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-amqp</artifactId>
      <version>${activemq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-blueprint</artifactId>
      <version>${activemq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-broker</artifactId>
      <version>${activemq.version}</version>
    </dependency>
.......
</dependencies>
</dependencyManagement>
           
【spring‐boot‐dependencies】項目實際是用來真正管理Spring Boot應用裡面的所有依賴包。有了【spring‐boot‐dependencies】項目以後我們建立的SpringBoot項目所需要的依賴包導入就不要在再配置版本和<dependencies>元素導入依賴,從【spring‐boot‐dependencies】項目中繼承就可以了。

1.2SpringBoot啟動器

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter</artifactId>

</dependency>

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-test</artifactId>

    <scope>test</scope>

</dependency>

注意命名規則:spring-boot-starter-xxxx  [SpingBoot的啟動器]

1)Spring-boot-starter:這是Spring Boot的核心啟動器,包含了自動配置、日志和YAML。

2)Spring-boot-starter-web: 幫助我們島嶼web子產品正常的運作所依賴的包

3)Spring-boot-starter-test: 幫我們導入但願測試子產品正常運作依賴包。

基本的啟動器

Spring Boot應用啟動器基本的一共有44種,具體如下:
1)spring-boot-starter:這是Spring Boot的核心啟動器,包含了自動配置、日志和YAML。
2)spring-boot-starter-actuator:幫助監控和管理應用。
3)spring-boot-starter-amqp:通過spring-rabbit來支援AMQP協定(Advanced Message Queuing Protocol)。
4)spring-boot-starter-aop:支援面向方面的程式設計即AOP,包括spring-aop和AspectJ。
5)spring-boot-starter-artemis:通過Apache Artemis支援JMS的API(Java Message Service API)。
6)spring-boot-starter-batch:支援Spring Batch,包括HSQLDB資料庫。
7)spring-boot-starter-cache:支援Spring的Cache抽象。
8)spring-boot-starter-cloud-connectors:支援Spring Cloud Connectors,簡化了在像Cloud Foundry或Heroku這樣的雲平台上連接配接服務。
9)spring-boot-starter-data-elasticsearch:支援ElasticSearch搜尋和分析引擎,包括spring-data-elasticsearch。
10)spring-boot-starter-data-gemfire:支援GemFire分布式資料存儲,包括spring-data-gemfire。
11)spring-boot-starter-data-jpa:支援JPA(Java Persistence API),包括spring-data-jpa、spring-orm、Hibernate。
12)spring-boot-starter-data-mongodb:支援MongoDB資料,包括spring-data-mongodb。
13)spring-boot-starter-data-rest:通過spring-data-rest-webmvc,支援通過REST暴露Spring Data資料倉庫。
14)spring-boot-starter-data-solr:支援Apache Solr搜尋平台,包括spring-data-solr。
15)spring-boot-starter-freemarker:支援FreeMarker模闆引擎。
16)spring-boot-starter-groovy-templates:支援Groovy模闆引擎。
17)spring-boot-starter-hateoas:通過spring-hateoas支援基于HATEOAS的RESTful Web服務。
18)spring-boot-starter-hornetq:通過HornetQ支援JMS。
19)spring-boot-starter-integration:支援通用的spring-integration子產品。
20)spring-boot-starter-jdbc:支援JDBC資料庫。
21)spring-boot-starter-jersey:支援Jersey RESTful Web服務架構。
22)spring-boot-starter-jta-atomikos:通過Atomikos支援JTA分布式事務處理。
23)spring-boot-starter-jta-bitronix:通過Bitronix支援JTA分布式事務處理。
24)spring-boot-starter-mail:支援javax.mail子產品。
25)spring-boot-starter-mobile:支援spring-mobile。
26)spring-boot-starter-mustache:支援Mustache模闆引擎。
27)spring-boot-starter-redis:支援Redis鍵值存儲資料庫,包括spring-redis。
28)spring-boot-starter-security:支援spring-security。
29)spring-boot-starter-social-facebook:支援spring-social-facebook
30)spring-boot-starter-social-linkedin:支援pring-social-linkedin
31)spring-boot-starter-social-twitter:支援pring-social-twitter
32)spring-boot-starter-test:支援正常的測試依賴,包括JUnit、Hamcrest、Mockito以及spring-test子產品。
33)spring-boot-starter-thymeleaf:支援Thymeleaf模闆引擎,包括與Spring的內建。
34)spring-boot-starter-velocity:支援Velocity模闆引擎。
35)spring-boot-starter-web:支援全棧式Web開發,包括Tomcat和spring-webmvc。
36)spring-boot-starter-websocket:支援WebSocket開發。
37)spring-boot-starter-ws:支援Spring Web Services。
Spring Boot應用啟動器面向生産環境的還有2種,具體如下:
1)spring-boot-starter-actuator:增加了面向産品上線相關的功能,比如測量和監控。
2)spring-boot-starter-remote-shell:增加了遠端ssh shell的支援。
最後,Spring Boot應用啟動器還有一些替換技術的啟動器,具體如下:
1)spring-boot-starter-jetty:引入了Jetty HTTP引擎(用于替換Tomcat)。
2)spring-boot-starter-log4j:支援Log4J日志架構。
3)spring-boot-starter-logging:引入了Spring Boot預設的日志架構Logback。
4)spring-boot-starter-tomcat:引入了Spring Boot預設的HTTP引擎Tomcat。
5)spring-boot-starter-undertow:引入了Undertow HTTP引擎(用于替換Tomcat)。
           

2.SpringBoot的主類

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = "com.wangxing.springboot")
public class Springbootdemo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Springbootdemo1Application.class, args);
    }
}
           

之是以說Springbootdemo1Application 是主類是因為它裡面包含了主方法

 public static void main(String[] args) {}

在這個主方法中有

SpringApplication.run(Springbootdemo1Application.class, args);

SpringApplication 将一個典型的 Spring 應用啟動的流程“模闆化”(這裡是動詞),在沒有特殊需求的情況下,預設模闆化後的執行流程就可以滿足需求了但有特殊需求也沒關系,SpringApplication 在合适的流程結點開放了一系列不同類型的擴充點,我們可以通過這些擴充點對 SpringBoot 程式的啟動和關閉過程進行擴充。

2.1通過SpringApplication設定修改啟動圖示

1)在resources檔案夾中建立banner.txt

banner.txt中的内容
'##::::'##:'########:'##:::::::'##::::::::'#######::
 ##:::: ##: ##.....:: ##::::::: ##:::::::'##.... ##:
 ##:::: ##: ##::::::: ##::::::: ##::::::: ##:::: ##:
 #########: ######::: ##::::::: ##::::::: ##:::: ##:
 ##.... ##: ##...:::: ##::::::: ##::::::: ##:::: ##:
 ##:::: ##: ##::::::: ##::::::: ##::::::: ##:::: ##:
 ##:::: ##: ########: ########: ########:. #######::
..:::::..::........::........::........:::.......:::
           

2)在主類中通過SpringApplication來設定啟動圖示 

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;

@SpringBootApplication
@ComponentScan(basePackages = "com.example")
public class Demo2Application {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(Demo2Application.class);
        springApplication.setBannerMode(Banner.Mode.CONSOLE);
        springApplication.run(args);
    }
}
           

運作結果圖: 

SpringBoot(三)

 3.SpringApplication的run方法的執行流程

        SringApplicaiton的run方法的實作是我們本次運作的主要路線圖,大緻流程可以歸納為:

1)如果我們是用的是SpringApplication的靜态run方法,那麼,這個方法裡面首先需要建立一個SpringApplication對象執行個體,然後調用這個建立好的SpringApplication的執行個體run方法。在SpringApplication執行個體初始化的時候,它會提前做幾件事:

        (1)根據classpath裡面是否存在某個特征類(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應該建立一個Web應用的ApplicationContext類型,還是建立一個标準Standalone應用使用的ApplicationContext類型

         (2)使用SpringFactoriesLoader在應用的classpath中查找并加載所有可用的ApplicationContextInitializer。

        (3)使用SpringFactoriesLoader應用的classpath中查找并加載可用的ApplicationListener。

        推斷并設定main方法定義類

2)SpringApplication執行個體初始化完成設定後,就開始執行run方法的邏輯,方法執行開始,首先周遊執行所有通過SpringFactoriesLoader可以查找到并加載的SpringApplicationRunLister,調用他們的stared()方法,告訴這些SpringApplicationRunListener,"SpringBoot應用開始執行~" 。

3)建立并配置目前SpringBoot應用将要使用的Environment(包括配置要是用的PropertySource以及Profile)

4)調用所有SpringApplicationRunListener的environmentPrepared()方法,告訴他們;“目前SpringApplication應用使用的environment準備好咯!”

5)如果SpringApplication的showBanner屬性被設定為true,則列印banner(Spring1.3x版本,這裡應該是基于Banner.Mode決定列印行為)。這一步的邏輯其實可以不關心。

6)根據使用者是否明确設定了applicationContextClass類型以為初始化階段的推斷結果,決定為目前的SpringBoot應用建立什麼類型的ApplicationContext并建立完成,然後根據條件決定是否添加ShutdownHook,決定是否使用自定義的BeanNameGenerator,決定是否使用自定義的ResourceLoader,當然最重要的,将之前準備好的Environment設定給建立好的ApplicationContext使用。

7)ApplicationContext建立好之後,SpringApplication會再次借助Spring-FactoriesLoader,查詢并加載,classpath中所有可用的ApplicationContext-Initializer,然後周遊調用這些ApplicationContextInitializer的initialize(applicationContext)方法來對已經建立的好的ApplicationContext進行進一步的處理。

8)周遊調用所有SpringApplicationRunListener的contextPrepared()方法,通告他們:“SpringBoot應用使用的ApplicationContext準備好了”。

9)最核心的一步,将之前通過@EnableAutoConfiguration擷取的所有配置以及其他形式的IoC容器配置架子啊到已經準備完成的ApplicationContext。

10)周遊調用所有的SpringApplicationRunListener的contextLoaded()方法,告知所有的SpringApplicationRunListener,ApplicationContext“裝填完畢”

11)調用ApplicationContext的refresh()方法,完成IoC容器可用的最後一道工序。

12)查找目前ApplicationContext中是否注冊有CommandLineRunner,如果有,則周遊執行他們。

13)正常情況下,周遊執行SpringApplicationRunListener的finished()方法,告知它們“搞定~”.(如果整個過程出現異常,則依然調用所有的SpringApplicationRunListener的finished()方法,隻不過一個完整的SpringBoot應用啟動完畢~)

整個過程看起來冗長無比,但其實很多都是一些事件通知的擴充點,如果我們将這些邏輯暫時忽略,那麼,其實整個 SpringBoot 應用啟動的邏輯就可以壓縮到極其精簡的幾步,如圖 1 所示。

SpringBoot(三)

 前後對比我們就可以發現,其實 SpringApplication 提供的這些各類擴充點近乎“喧賓奪主”,占據了一個 Spring 應用啟動邏輯的大部分“江山”,除了初始化并準備好ApplicationContext,剩下的大部分工作都是通過這些擴充點完成的,是以,我們接下來對各類擴充點進行逐一剖析。

無奈源于不夠強大

SpringBoot(三)