一、简介:
作用:监听容器中发布的事件,完成事件驱动模型开发。
自定义一个监听器,监听ApplicationEvent及其下面的子事件;-----实现ApplicationEvent接口方式
1)写一个监听器(ApplicationListener的实现类)来监听某个事件(ApplicationEvent及其子类)
重写方法 void onApplicationEvent(ApplicationEvent event){}
//当容器中发布此事件(event)后,该方法会被触发;
2)把监听器加入到容器中;
3)只要容器中有相关事件的发布,我们就能监听到这个事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发步这个事件;
4)发布一个事件:
applicationContext.publishEvent(ApplicationEvent event);
eg:ac.publishEvent(new ApplicationEvent(new String("我发布的事件")) {});
二、原理
针对监听到的三个事件进行原理分析:
1、ContextRefreshedEvent事件
1)容器创建对象:refresh()
2)finishRefresh();容器刷新完成;---会发布ContextRefreshedEvent事件、自定义发布的事件;
2、自己发布的事件、ContextRefreshedEvent、ContextClosedEvent
都会走下面的流程:
2.1)publishEvent(new ContextRefreshedEvent(this));
2.1.1)获取事件的多播器(派发器):getApplicationEventMulticaster();
2.1.2)void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);派发事件;
2.1.3)获取到所有的ApplicationListeners;Collection<ApplicationListener<?>>
getApplicationListeners( ApplicationEvent event, ResolvableType eventType)
a)如果有executor,可以支持使用executor进行异步派发;
Executor executor = getTaskExecutor();
b)否则,同步的方式直接执行listener方法;invokeListener(listener, event);
拿到listener回调onApplicationEvent(ApplicationEvent event){}
3、获取事件多播器:getApplicationEventMulticaster
1)创建容器对象,refresh()
//初始化EventMulticaster
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
4、容器中有哪些监听器?
1)容器创建对象refresh();
2)registerListeners();
从容器中拿到所有的监听器,把他们注册到ApplicationEventMulticaster中;’
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
三、测试代码:
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件:"+event);
}
}
@Configuration
public class ExtConfig {
@Bean
public MyApplicationListener myApplicationListener(){
return new MyApplicationListener();
}
}
@Test
public void Test1(){
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件
ac.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
ac.close();
}
结果:
四、注解方式实现自定义监听器
@EventListener
4.1、测试代码
@Service(value="users")
public class UserService {
@EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService监听到的事件:"+event);
}
}
@Test
public void Test1(){
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件
ac.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
ac.close();
}
4.2、原理分析
即使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
SmartInitializingSingleton原理:该接口只有一个方法:void afterSingletonsInstantiated();
何时调用?
1)ioc容器创建对象并调refresh();
2)finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例Bean;
调用过程:beanFactory.preInstantiateSingletons();-->smartSingleton.afterSingletonsInstantiated();