一、.pom.xml配置packging為war
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.edu.tju</groupId><artifactId>springbootmybatis2023</artifactId><version>1.0.0</version><packaging>war</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.6</version><relativePath/></parent><dependencies><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-validation</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.6</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.30</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
二、在和啟動類相同的路徑下創建一個類:
package cn.edu.tju;import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.SpringServletContainerInitializer;public class TomcatSpringBoot extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {System.out.println("called......");return builder.sources(Start.class);}
}
這個類的configure方法會被Servlet容器調用。
三、打成war包,在外置的tomcat容器或者idea里運行。
#######################################################################
原理:
SpringBoot web的jar包中META-INF 目錄的services子目錄有個javax.servlet.ServletContainerInitializer文件,該文件的內容是org.springframwork.web.SpringServletContainerInitializer,所以Tomcat啟動的時候會調用SpringServletContainerInitializer的Startup方法,代碼如下
在這個方法中首先實例化了webApplicationInitializerClasses中的類,然后分別調用了它們的onStartup方法。
都傳入了哪些WebApplicationInitializer類呢?我們自己定義的類TomcatSpringBoot代碼如下:
它繼承了SpringBootServletInitializer,SpringBootServletInitializer代碼如下:
所以最終當Tomcat容器啟動時會調用SpringBootServletInitializer的onStartup方法,其中調用了createRootApplicationContext方法,代碼如下:
從劃紅線的地方可以看到,首先會把我們的SpringBoot啟動類傳進來,然后使用SpringBootApplicationBuilder通過啟動類創建了一個SpringBootApplication對象,最后調用了一個run方法,并把新創建的SpringApplication傳進去了,這run方法代碼如下:
就是直接調用了SpringApplication對象的run方法,然后把結果返回。