您的位置:首页 >Spring监听器之ApplicationListener原理及源码深度解析
发布于2026-04-27 阅读(0)
扫一扫,手机访问
在Spring框架中,事件驱动模型是一个核心但常被忽视的机制。它主要围绕几个关键事件展开:ContextRefreshedEvent、开发者自定义发布的事件(如示例中的IOCTest_Ext$1[source=我发布的事件]),以及ContextClosedEvent。
那么,这些事件是如何产生并被处理的呢?我们不妨深入到源码层面,一探究竟。
事件的生命周期与触发时机
refresh()方法。refresh()流程执行完毕,即容器刷新完成时,会通过finishRefresh()方法发布ContextRefreshedEvent事件。applicationContext.publishEvent()主动发布事件。【事件发布流程】源码执行流程
当调用publishEvent(new ContextRefreshedEvent(this));时,幕后发生了什么?
getApplicationEventMulticaster()获取事件的多播器(或称派发器)。multicastEvent来派发事件。ApplicationListener。这个过程大致如下:
for (final ApplicationListener> listener : getApplicationListeners(event, type)) {
Executor,Spring会使用它进行异步派发,提升性能。Executor,则采用同步方式,直接调用invokeListener(listener, event);。最终,会回调监听器的onApplicationEvent方法。【事件多播器(派发器)】源码执行流程
这个关键的派发器又是如何初始化的呢?
refresh()方法。initApplicationEventMulticaster()方法中,Spring会初始化ApplicationEventMulticaster。
id="applicationEventMulticaster"的组件。SimpleApplicationEventMulticaster(beanFactory)实例,并将其注册到容器中。这样一来,其他需要派发事件的组件就能自动注入这个多播器了。【容器中有哪些监听器】源码执行流程
监听器又是如何被收集并注册到派发器中的?
refresh()方法。registerListeners()阶段,Spring会从容中找出所有类型为ApplicationListener的Bean。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); //将listener注册到ApplicationEventMulticaster中 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
SmartInitializingSingleton 原理
除了事件监听,还有一个与之相关的接口SmartInitializingSingleton,其核心方法是afterSingletonsInstantiated()。它的执行时机是:
refresh()。finishBeanFactoryInitialization(beanFactory)阶段,初始化所有剩余的单例Bean。
getBean())。SmartInitializingSingleton接口。如果是,则调用其afterSingletonsInstantiated()方法。理论说得再多,不如动手一试。ApplicationListener是监听容器中发布事件的核心接口,它正是Spring事件驱动模型开发的基石。
该接口定义为:public interface ApplicationListener,意味着它可以监听ApplicationEvent及其所有子类事件。
使用起来,通常遵循以下几个步骤:
ApplicationListener接口,或者更简单地,在任意Bean的方法上使用@EventListener注解。后者的原理在于,Spring容器中有一个EventListenerMethodProcessor处理器,专门负责解析方法上的这个注解。@Component、@Service等注解,将监听器类装配到Spring容器中。ContextRefreshedEvent:当容器刷新完成,所有Bean都完全创建后发布。ContextClosedEvent:当容器关闭时发布。ApplicationContext的地方,调用applicationContext.publishEvent()方法,即可发布自定义事件。首先,我们可以定义一个实现ApplicationListener接口的类。这样,它就能监听所有类型的ApplicationEvent。别忘了用@Component将其装配到Spring容器中。
package com.atguigu.ext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener{ //当容器中发布此事件以后,方法触发 @Override public void onApplicationEvent(ApplicationEvent event) { // TODO Auto-generated method stub System.out.println("收到事件:"+event); } }
另一种更灵活的方式是使用@EventListener注解。你可以将它标注在任何一个Bean的方法上。注意,@EventListener(classes={ApplicationEvent.class})中的classes属性可以指定多个要监听的类,用逗号分隔即可。
package com.atguigu.ext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。监听到的事件:"+event);
}
}
接下来,需要一个配置类来扫描并加载这些组件。
@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
@Bean
public Blue blue(){
return new Blue();
}
}
最后,我们编写测试代码来验证。在测试中,我们不仅会触发Spring内置的容器刷新和关闭事件,还会主动发布一个自定义事件(这里使用了匿名内部类来创建ApplicationEvent)。
package com.atguigu.test;
import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.atguigu.ext.ExtConfig;
public class IOCTest_Ext {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
applicationContext.close();
}
}
运行结果:


结果说明:从控制台输出可以清晰看到,Spring容器自身在刷新和关闭时会发布事件,这些事件被我们自定义的监听器成功捕获。同时,我们主动发布的那个自定义事件“我发布的事件”,也同样被监听到了。这充分证明了,无论是Spring内置的事件,还是开发者自定义的事件,只要监听器注册得当,整个事件驱动模型就能顺畅运转。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9