springboot使用tomcat浅析

springboot使用tomcat浅析

关于外部tomcat

maven pom配置

xml 复制代码
// 打包时jar包改为war包
<packaging>war</packaging>

// 内嵌的tomcat的scope标签影响范围设置为provided,只在编译和测试时有效,打包时不带入
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

启动类需继承SpringBootServletInitializer并复写configure方法

java 复制代码
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder){
        return builder.sources(this.getClass());
	// 还可以显式声明应用类型WebApplicationType
	// return builder.sources(this.getClass()).web(WebApplicationType.NONE);
}

应用类型WebApplicationType分三种

复制代码
NONE:应用程序不作为web应用启动,不启动内嵌的服务。
SERVLET:应用程序以基于servlet的web应用启动,需启动内嵌servlet web服务。
REACTIVE:应用程序以响应式web应用启动,需启动内嵌的响应式web服务。

configure调用关系

关于内嵌tomcat

利用了构造函数new Tomcat()创建tomcat对象。可以引入以下maven依赖。

xml 复制代码
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>xxx</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <version>xxx</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>xxx</version>
</dependency>

消失的Web.xml

servlet3.0后springMVC提供了WebApplicationInitializer 接口替代了Web.xml。而JavaConfig的方式替代了springmvc-config.xml

servlet3.0特性之ServletContainerInitializer

参考8.2.4节。也称SCI接口,约定了servlet容器启动时,会扫描当前应用里面每一个jar包的ServletContainerInitializer的实现,利用了SPI 机制。可参考tomcat的org.apache.catalina.startup.ContextConfig#processServletContainerInitializers方法。

java 复制代码
/**
 * Scan JARs for ServletContainerInitializer implementations.
 */
protected void processServletContainerInitializers()

tomcat启动时触发调用了configureStart方法

springMVC之ServletContainerInitializer实现

调用链入口

复制代码
spring-web-xxx.jar里META-INF/services/javax.servlet.ServletContainerInitializer文件,
定义了实现类org.springframework.web.SpringServletContainerInitializer

onStartup调用关系

关于@HandlesTypes注解

属于servlet3.0规范,在javax.servlet.annotation包里。作用是在onStartup方法的入参上,传入注解@HandlesTypes定义的类型

在springMVC上的使用

java 复制代码
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

	@Override
	public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {
        ... 
    }
    ...
}

在tomcat上的使用,调用链为

复制代码
参考org.apache.catalina.startup.ContextConfig
1)在processServletContainerInitializers方法,记录下注解名
2)在processAnnotationsStream方法,使用bcel字节码工具org.apache.tomcat.util.bcel直接读取字节码文件,判断是否与记录的注解类名相同
3)若相同再通过org.apache.catalina.util.Introspection类load为Class对象,最后保存起来
4)在Step 11中交给org.apache.catalina.core.StandardContext,也就是tomcat实际调用ServletContainerInitializer.onStartup()的地方。
相关推荐
DCTANT1 天前
【原创】使用更优雅的方式改造MyBatisPlus逻辑删除插件
spring boot·后端·mysql·kotlin·mybatis·mybatisplus
上进小菜猪1 天前
基于 YOLOv8 的太阳能电池片缺陷智能检测识别实战 [目标检测完整源码]
后端
Rysxt_1 天前
Go语言:现代编程的效率与并发之选
开发语言·后端·golang
l***21781 天前
Spring Boot 整合 log4j2 日志配置教程
spring boot·单元测试·log4j
内存不泄露1 天前
基于 Spring Boot 的医院预约挂号系统(全端协同)设计与实现
java·vue.js·spring boot·python·flask
Mr -老鬼1 天前
Rust 知识图-谱基础部分
开发语言·后端·rust
袁慎建@ThoughtWorks1 天前
如何发布自定义 Spring Boot Starter
java·spring boot·后端
IT_陈寒1 天前
SpringBoot 3.0实战:10个高效开发技巧让你的启动时间减少50%
前端·人工智能·后端
源代码•宸1 天前
Golang原理剖析(string面试与分析、slice、slice面试与分析)
后端·算法·面试·golang·扩容·string·slice
回家路上绕了弯1 天前
Spring Boot多数据源配置实战指南:从选型到落地优化
分布式·后端