一、.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方法,然后把结果返回。