Springboot中,Tomcat啟動war包的流程

將一個SpringBoot項目,打成war包

<!-- 1. 修改POM依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

<!-- 2. 修改啟動類,繼承SpringBootServletInitializer類,重寫configure方法 -->
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class WarApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(WarApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WarApplication.class);
    }
}

Springboot項目打war包為何要繼承SpringBootServletInitializer,重寫的configure在什麼時候被調用的?

這裡涉及到一個Servlet3.0的新特性按需載入(詳情可參考//www.oracle.com/technetwork/cn/community/4-servlet-3-324302-zhs.pdf),按需載入主要做了:

1、Web應用啟動時,創建當前Web應用導入jar包中的ServletContainerInitializer類的實例
2、ServletContainerInitializer 類必須放在jar包的 META-INF/services目錄下,文件名稱為javax.servlet.ServletContainerInitializer
3、文件的內容指向ServletContainerInitializer實現類的全路徑
4、使用@HandlesTypes 在我們應用啟動的時候,將標註的類資訊(@HandlesTypes註解的value值)傳遞給ServletContainerInitializer的應用類

下面是Tomcat啟動的整個調用過程: