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()的地方。
相关推荐
小朱爱编程1231 分钟前
我用 Jev 做了三个实用工具:整理标签页、分诊飞书反馈、找回 GitHub 收藏
java·开发语言·人工智能·后端·python·架构·ai编程
明月_清风36 分钟前
企业买了 Codex、WorkBuddy,AI 为什么还是没落地?我用 FDE + AKA 做深度定制
人工智能·后端
喵个咪1 小时前
RushWind Admin — 用 Rust 写的企业级中后台,开源了
后端·rust·开源
喵个咪1 小时前
RushWind Admin — 契约驱动:203 条路由零手写的工程化拆解
后端·rust·开源
明月_清风1 小时前
只会 Vibe Coding 的程序员,为什么可能会被淘汰?
后端·ai编程
喵个咪1 小时前
Go 写业务,Rust 扛底盘:一套可落地的混合架构
后端·rust·go
小小张说故事2 小时前
Python logging 日志不输出?根源在 propagate 这条链上
后端·python
MZ_ZXD0012 小时前
【关注可白嫖源码】--课程设计--毕业设计-- 42557基于springboot的大学生体质健康管理系统
spring boot·课程设计·毕设·大作业·程序开发·程序定制·毕设代做
ZealSinger2 小时前
Go slog生产落地LevelVar与共存
开发语言·后端·golang·go
w***48823 小时前
SpringBoot整合easy-es
spring boot·后端·elasticsearch