1 ApplicationListener
1、作用
-
监听容器中发布的事件,完成事件驱动模型开发;
-
public interface ApplicationListener 监听 ApplicationEvent 及其下面的子事件;
2、步骤
-
写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
监听器的两种实现方式:
- 实现ApplicationListener接口
- 标注注解@EventListener;
-
把监听器加入到容器;
-
只要容器中有相关事件的发布,我们就能监听到这个事件;
例如:
-
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
-
ContextClosedEvent:关闭容器会发布这个事件;
-
-
发布一个事件:
applicationContext.publishEvent();
@Component public class MyApplicationListener implements ApplicationListener<ApplicationEvent> { //当容器中发布此事件以后,方法触发 @Override public void onApplicationEvent(ApplicationEvent event) { // TODO Auto-generated method stub System.out.println("收到事件:"+event); } } public class IOCTest_Ext { @Test public void test01(){ //ContextRefreshedEvent AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); //发布事件;IOCTest_Ext$1[source=我发布的事件] applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) { }); //ContextClosedEvent applicationContext.close(); } }
3、原理
监听到的三个事件:
ContextRefreshedEvent、IOCTest_Ext$1[source=我发布的事件]、ContextClosedEvent;
-
ContextRefreshedEvent事件:
-
容器创建对象:调用refresh()方法;
-
refresh()中调用finishRefresh():容器刷新完成之后调用;执行publishEvent(new ContextRefreshedEvent(this)) 发布ContextRefreshedEvent事件
-
【事件发布流程】
publishEvent(new ContextRefreshedEvent(this));
获取事件的多播器(派发器):getApplicationEventMulticaster()
然后执行 multicastEvent派发事件:
【multicastEvent执行流程】
- 获取到所有的ApplicationListener;
for (final ApplicationListener<?> listener : getApplicationListeners(event, type))
- 如果有Executor,可以支持使用Executor进行异步派发;
Executor executor = getTaskExecutor();
- 否则,同步的方式直接执行listener方法;invokeListener(listener, event);
拿到listener回调onApplicationEvent方法;
-
自己发布事件;
-
容器关闭会发布ContextClosedEvent;
【事件多播器(派发器)来源】
-
容器创建对象:执行refresh();
-
refresh()中调用initApplicationEventMulticaster():初始化ApplicationEventMulticaster;
-
先去容器中找有没有id="applicationEventMulticaster"的组件;
-
如果没有就执行:
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;
-
【容器中监听器来源】
-
容器创建对象:执行refresh();
-
refresh()中调用registerListeners();
//从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中; String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); //将listener注册到ApplicationEventMulticaster中 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
2 @EventListener与SmartInitializingSingleton
1、监听器的两种实现方式:
- 实现ApplicationListener接口
- 标注注解@EventListener;
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。监听到的事件:"+event);
}
}
2、@EventListener原理
使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
因为EventListenerMethodProcessor implements SmartInitializingSingleton,所以接下来分析 SmartInitializingSingleton 的原理
3、SmartInitializingSingleton 原理
-
该接口之包含一个 afterSingletonsInstantiated() 方法;
-
ioc容器创建对象并refresh();
-
refresh()中调用finishBeanFactoryInitialization(beanFactory):初始化剩下的单实例bean;
-
先创建所有的单实例bean;getBean();
-
获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
如果是就调用afterSingletonsInstantiated();
-