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()的地方。
相关推荐
xmjd msup16 分钟前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
Vane118 分钟前
从零开发一个AI插件,经历了什么?
人工智能·后端
9523640 分钟前
SpringBoot统一功能处理
java·spring boot·后端
rleS IONS1 小时前
SpringBoot中自定义Starter
java·spring boot·后端
DevilSeagull1 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
TeDi TIVE2 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
雨辰AI2 小时前
SpringBoot3 + 人大金仓 V9 微服务监控实战|Prometheus+Grafana+SkyWalking 全链路监控
数据库·后端·微服务·grafana·prometheus·skywalking
二哈赛车手2 小时前
新人笔记---ES和kibana启动问题以及一些常用的linux的错误排查方法,以及ES,数据库泄密解决方案[超详细]
java·linux·数据库·spring boot·笔记·elasticsearch
Nicander3 小时前
理解 mybatis 源码:vibe-coding一个mini-mybatis
后端·mybatis
小呆呆6663 小时前
Codex 穷鬼大救星
前端·人工智能·后端