springboot项目不退出的原因

一、普通java程序vs springboot项目的本质

维度 普通 Java 程序(如 java HelloWorld) Spring Boot 服务
运行模式 执行完 main() 就结束 main() 启动后阻塞等待,不结束
生命周期 秒级/分钟级 天级/月级(7×24 运行)
与 JVM 关系 JVM 随程序结束而退出 JVM 长期存活,请求在已运行的 JVM 内处理
类加载时机 启动时一次性加载 启动时加载核心类,运行时可能懒加载
JIT 编译时机 运行期间触发 运行期间持续触发,服务越久性能越好

二、Spring Boot 为什么能"一直运行不结束"?

核心:非守护线程阻塞

java 复制代码
// SpringApplication.run() 的核心逻辑(简化)
public ConfigurableApplicationContext run(String... args) {
    // 1. 创建 Spring 上下文
    ConfigurableApplicationContext context = createApplicationContext();
    
    // 2. 刷新上下文(加载 Bean、启动内嵌 Tomcat)
    refreshContext(context);
    
    // 3. 发布启动完成事件
    listeners.started(context);
    
    // 4. 调用 Runner(CommandLineRunner/ApplicationRunner)
    callRunners(context, args);
    
    // 5. 返回上下文,但 main 线程在这里做了什么?
    return context;
}

// 这里需要再去学习下springboot的启动过程

关键点:内嵌 Tomcat/Jetty/Undertow 启动了非守护线程。

java 复制代码
// Tomcat 启动时会创建线程池处理请求
// 这些线程默认是 非守护线程(non-daemon)
Executor executor = new ThreadPoolExecutor(
    corePoolSize, 
    maxPoolSize, 
    keepAliveTime, 
    TimeUnit.SECONDS, 
    new LinkedBlockingQueue<>(),
    new CustomThreadFactory()  // 默认创建的是非守护线程
);

JVM 退出条件:所有非守护线程结束。

java 复制代码
main 线程启动
    │
    ▼
启动 Tomcat(创建非守护线程:Acceptor、Poller、Worker 线程)
    │
    ▼
main 线程执行完 run() 方法
    │
    ▼
main 线程结束,但 JVM 不退出
    │
    ▼
Tomcat 的 Acceptor 线程仍在监听端口(如 8080)
    │
    ▼
有新请求 → Worker 线程从线程池取出处理
    │
    ▼
请求处理完 → Worker 线程归还线程池,**不销毁 JVM**

只要还有非守护线程在运行,JVM 就不会退出。Spring Boot 通过内嵌 Web 服务器维持这些线程。

相关推荐
CoderYanger1 分钟前
Java EE 进阶:5. Spring IoC&DI(第二弹):Spring IoC
java·开发语言·spring boot·spring·面试·职场和发展·java-ee
aiks_yuan4 分钟前
Spring Boot 4 注入 ObjectMapper 报找不到 Bean:升级 Jackson 3 的改法和过渡方案(4.1.2 实测)
spring boot
用户别睡觉23 分钟前
自己搭的中文 PDF RAG 接了 Redis 缓存、跑了 RAGAS,以为能写“提速多少、准确率多少”,结果两个都没按预期来。
后端
彭亚川Allen30 分钟前
985 在职研究生到底怎么样?是不是水硕?是不是.....?
前端·后端·程序员
乘风24832 分钟前
# 我做了个会遗忘的 AI 记忆,召回率反而从 8% 涨到 100%
后端
Rain的Java大神之路1 小时前
面试被LeetCode 27(移除元素)问懵?别再用两层 for 循环了:一道“简单题”吃透双指针原地删除,附面试加分话术 + 11 个避坑清单
后端·leetcode·面试
悟天特斯1 小时前
安防一体化:从“各管各的“到“全局联动“
java·大数据·网络·人工智能·物联网
70后写java的老码农1 小时前
Spring Boot 3.x + ShardingSphere 5.x + MyBatis-Plus 3.x:订单分库分表实战(含两个踩坑记录)
java
霸道流氓气质1 小时前
AI 翻译插件:翻译记忆级联复用、术语混合检索与结构化质量门禁的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
斯维赤1 小时前
OCR到底是接入第三方API 还是自己封装?
java·ocr