关于Spring JavaWeb工程中的ContextRefreshedEvent事件
在应用启动时,通常想在此时预加载一些资源,全局使用。
Spring会在操作应用上下文时,使用ApplicationEventPublisher触发相关ApplicationContextEvent,我们可以监听这些事件来做一些事情。
Spring中ApplicationContextEvent有以下几种:
其中ContextRefreshedEvent的执行时机为:
1 Event raised when an {@code ApplicationContext} gets initialized or refreshed.
我们通常会在Spring加载或刷新应用上下文时,也重新刷新下我们预加载的资源,我们就可以通过监听ContextRefreshedEvent来做这样的事情。
代码如下:
1 @Component 2 public class SpringHandlersProvider implements ApplicationListener<ContextRefreshedEvent> { 3 Lists<XXX> handlerList = Lists.newHashList(); 4 @Override 5 public void onApplicationEvent(ContextRefreshedEvent event) { 6 //do something 7 handlerList.add(xxx); 8 } 9 }
但对于tomcat工程来说,我们一般会加载两个上下文容器一个父容器,一个mvc子容器
- 父容器{@code ContextRefreshedEvent[source=Root WebApplicationContext: startup date [Thu Sep 29 14:52:08 CST 2016]; root of context hierarchy]}
- mvc容器{@code ContextRefreshedEvent[source=WebApplicationContext for namespace 'springmvc-servlet': startup date [Thu Sep 29 14:52:34 CST 2016]; parent: Root WebApplicationContext]}
这样就会触发两次ContextRefreshedEvent事件,导致监听此事件所作的逻辑执行两次。
避免方法:
1:只在加载父容器时,执行一次
1 @Component 2 public class SpringHandlersProvider implements ApplicationListener<ContextRefreshedEvent> { 3 Lists<XXX> handlerList = Lists.newHashList(); 4 @Override 5 public void onApplicationEvent(ContextRefreshedEvent event) { 6 if (Predicates.isNull().apply(event.getApplicationContext().getParent())) { 7 //do something 8 handlerList.add(xxx); 9 } 10 } 11 }
2:每次执行onApplicationEvent()方法时就将存放资源的容器清空下
1 @Component 2 public class SpringHandlersProvider implements ApplicationListener<ContextRefreshedEvent> { 3 Lists<XXX> handlerList = Lists.newHashList(); 4 @Override 5 public void onApplicationEvent(ContextRefreshedEvent event) { 6 handlerList.clear(); 7 8 //do something 9 handlerList.add(xxx); 10 } 11 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异