Spring MVC 的容器何时启动,何时关闭
·
Spring MVC容器的启动和关闭时机与部署方式密切相关。
主要有两种部署方式:传统WAR包部署和Spring Boot嵌入式容器部署。
1. 传统WAR包部署(外部Servlet容器:Tomcat、Jetty等)
启动时机
web.xml
<!-- web.xml 配置 -->
<web-app>
<!-- 1. 根容器(Service、Repository等)启动 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2. Spring MVC容器(Controller、HandlerMapping等)启动 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启动顺序:应用启动时立即加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
#启动流程:
Servlet容器启动 → 应用部署
ContextLoaderListener.contextInitialized() → 创建根WebApplicationContext(父容器)
DispatcherServlet.init() → 创建WebApplicationContext(子容器,继承父容器)
所有单例Bean初始化完成 → 应用就绪
#关闭时机
// 关闭流程:
1. Servlet容器关闭(如关闭Tomcat)
2. ContextLoaderListener.contextDestroyed() → 关闭根容器
3. DispatcherServlet.destroy() → 关闭MVC容器
4. 所有Bean的@PreDestroy方法执行 → 资源清理
2. Spring Boot嵌入式容器部署
#启动时机
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 容器在此启动!
SpringApplication.run(Application.class, args);
}
}
#启动流程:
SpringApplication.run() 调用
创建统一的ApplicationContext(不再区分根容器和MVC容器)
嵌入式Servlet容器(Tomcat/Netty)启动
DispatcherServlet自动注册
所有Bean初始化完成
应用开始监听端口
#关闭时机
优雅关闭(推荐)
application.yaml
# application.yml
server:
shutdown: graceful # 优雅关闭
spring:
lifecycle:
timeout-per-shutdown-phase: 30s # 等待超时时间
#关闭方式:
Ctrl+C 发送SIGINT信号
发送SIGTERM信号:kill -15 <pid>
通过Actuator端点(如果配置了):
curl -X POST http://localhost:8080/actuator/shutdown
#关闭流程:
// Spring Boot 优雅关闭流程
1. 收到关闭信号
2. 停止接收新请求
3. 等待正在处理的请求完成(最多等待timeout时间)
4. 关闭ApplicationContext
5. 销毁所有Bean,执行@PreDestroy
6. 关闭嵌入式Servlet容器
7. JVM退出
3. 关键生命周期回调
@Component
public class LifecycleExample {
// 启动时执行
@PostConstruct
public void init() {
System.out.println("Bean初始化完成");
}
// 关闭时执行
@PreDestroy
public void cleanup() {
System.out.println("Bean销毁前清理资源");
}
}
// 实现接口方式
@Component
public class LifecycleListener implements SmartLifecycle {
private boolean isRunning = false;
@Override
public void start() {
isRunning = true;
System.out.println("容器启动时调用");
}
@Override
public void stop() {
isRunning = false;
System.out.println("容器关闭时调用");
}
@Override
public boolean isRunning() {
return isRunning;
}
}
总结
部署方式 |启动时机 |关闭时机 |特点
传统WAR |Servlet容器启动时 |Servlet容器关闭时 |父子容器结构,生命周期由外部容器管理
Spring Boot |SpringApplication.run()调用时 |收到关闭信号时 |统一容器,支持优雅关闭,更现代化
#核心要点:
Spring MVC容器的生命周期与Servlet容器紧密绑定
Spring Boot简化了生命周期管理,提供更友好的启停控制
生产环境推荐使用Spring Boot的优雅关闭机制
更多推荐


所有评论(0)