关于IDE中嵌入式Tomcat运行Spring Web应用的两个技术问题
问题解答
1. Maven项目需手动添加Tomcat依赖,Gradle无需的原因
核心原因是你的项目打包方式设为了war:
- Spring Boot的Maven父项目(
spring-boot-starter-parent)针对war打包场景,会自动将spring-boot-starter-web自带的嵌入式Tomcat依赖的scope设为provided——这是为了避免部署到外部Tomcat时出现依赖冲突。但本地运行时,IDE需要这个依赖启动嵌入式容器,所以得手动添加spring-boot-starter-tomcat依赖(并去掉provided设置)。 - Gradle的Spring Boot插件对war打包的处理更智能:它默认会在本地运行的
bootRun任务中自动包含嵌入式Tomcat依赖,不需要手动添加就能正常启动容器。
2. Tomcat依赖设为provided后应用启动即终止的原因
provided scope的作用是让依赖仅在编译、测试阶段可用,运行时不会被加载到类路径。当你这么设置后:
- Spring Boot启动时找不到嵌入式Tomcat的相关类,就不会启动Web容器,也就没有能维持JVM运行的后台线程(比如Tomcat的请求监听线程)。
- Spring上下文初始化完成后,主线程没有需要等待的任务,直接退出,触发关闭钩子销毁连接池、EntityManagerFactory等资源,导致应用启动后立刻终止。
取消provided设置后,Tomcat依赖会被包含到运行时类路径,Spring Boot正常启动嵌入式Tomcat,容器的后台线程会保持JVM运行,应用就能持续以服务器模式运行。
从你提供的日志也能验证这一点:启动完成后立刻触发了ionShutdownHook,开始关闭各种资源,这就是没有Web容器维持运行的典型表现。
内容的提问来源于stack exchange,提问作者kakoli
相关产品推荐
相关产品推荐

