Spring 4.2+ 的 ConfigurableApplicationContext 实现 AutoCloseable,可直接用于 try-with-resources 自动关闭容器、销毁 Bean;低版本不支持,需用 try-finally 手动 close。

Spring 的 ConfigurableApplicationContext 实现了 AutoCloseable 接口(自 Spring 4.2 起),因此可以直接用于 try-with-resources 语句,实现自动关闭容器、释放资源(如关闭 Bean 生命周期、销毁单例 Bean、释放监听器等)。
确保使用支持 AutoCloseable 的 Spring 版本
Spring 4.2 及以上版本中,ConfigurableApplicationContext 继承自 AutoCloseable,调用 close() 方法即触发标准的上下文关闭流程。低于该版本(如 Spring 4.1 或更早)不支持,强行使用会编译失败。
正确写法:直接在 try-with-resources 中声明上下文
只需将容器创建语句放在 try 括号内,无需手动调用 close():
try (ConfigurableApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class)) {
MyService service = context.getBean(MyService.class);
service.doSomething();
} // 自动调用 context.close()
注意:
• 不要再在 try 块内或 finally 中显式调用 context.close(),否则会抛出 IllegalStateException(重复关闭);
• 上下文必须是 ConfigurableApplicationContext 类型(如 AnnotationConfigApplicationContext、ClassPathXmlApplicationContext),普通 ApplicationContext 接口不保证可关闭。
常见陷阱与注意事项
-
避免提前赋值变量:不要先声明变量再赋值,否则无法满足 try-with-resources 的“有效 final”要求:
❌ 错误:ConfigurableApplicationContext ctx; try (ctx = new ...) { ... } -
异常处理需谨慎:如果构造上下文时抛出异常(如配置错误),try-with-resources 不会执行 close(因为对象未成功创建),无需担心;但若 close() 过程中抛异常(如 Bean 销毁失败),会被抑制(suppressed),可通过
Throwable.getSuppressed()获取 - Web 环境慎用:在 Servlet 容器(如 Tomcat)中,通常由 Spring 的 ContextLoaderListener 管理上下文生命周期,不应手动创建并用 try-with-resources 关闭,否则会破坏容器集成
替代方案:手动 close + try-finally(兼容旧版本)
若项目仍在使用 Spring 4.1 或更早版本,可用传统方式确保关闭:
立即学习“Java免费学习笔记(深入)”;
ConfigurableApplicationContext context = null;
try {
context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService service = context.getBean(MyService.class);
service.doSomething();
} finally {
if (context != null) {
context.close();
}
}
这种方式逻辑清晰、兼容性强,但代码略冗长,且容易遗漏 null 判断或忘记 close。


















