Spring Boot关闭生命周期日志顺序是否正确?ExecutorService是否应最后关闭?
Spring Boot 应用关闭时的组件销毁顺序疑问
我在关闭Spring Boot应用时看到如下日志序列,想请教该事件发生顺序是否正确?
2022-09-15 15:30:20.458 INFO 81214 --- [ Thread-16] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' 2022-09-15 15:30:22.518 INFO 81214 --- [ Thread-16] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2022-09-15 15:30:22.520 INFO 81214 --- [ Thread-16] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2022-09-15 15:30:22.529 INFO 81214 --- [ Thread-16] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
根据我的理解,ExecutorService作为主ThreadPoolExecutor应该是最后关闭的,请问应用与数据库建立的连接是否无法安全关闭?
这个销毁顺序是正常且完全安全的,核心逻辑如下:
- Spring Bean遵循「初始化顺序反转销毁」规则:
初始化阶段的顺序是HikariDataSource→EntityManagerFactory→ThreadPoolTaskExecutor;销毁时则完全反转,因此会先关闭线程池,再清理JPA工厂,最后销毁数据源。 - 线程池的关闭是安全可控的:
ThreadPoolTaskExecutor执行shutdown()时,会等待所有正在运行的任务执行完毕后再终止,不会强制中断任务。如果线程池内的任务包含数据库操作,这些任务会正常完成,不会出现连接在使用中就被销毁的情况。 - 数据库资源的销毁时机合理:
EntityManagerFactory关闭时会清理所有活跃的EntityManager,确保所有JPA层面的数据库交互都已收尾;最后关闭Hikari数据源时,已经没有活跃的数据库连接在使用,因此连接池可以安全完成 shutdown。
另外需要纠正你的误解:主线程池不需要最后关闭。正确的销毁逻辑是依赖资源的Bean先销毁,被依赖的Bean后销毁。这里线程池不依赖数据库资源,反而如果线程池后关闭,可能出现线程池提交新任务时,数据库资源已被销毁的风险,当前的顺序反而规避了这种问题。
内容的提问来源于stack exchange,提问作者Dishant Patel
相关产品推荐
相关产品推荐

