博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot源码学习(七)
阅读量:4210 次
发布时间:2019-05-26

本文共 5264 字,大约阅读时间需要 17 分钟。

通过前期的学习,我们发现在onRefresh方法之前的操作都是准备工作。在onRefresh方法之前的准备工作中,目前就剩下initApplicationEventMulticaster方法了。因为通过invokeBeanFactoryPostProcessors方法之后,所有需要的类均已经注册到beanDefinitionMap中,所以这块也应该是从beanDefinitionMap中获取特定接口的类并进行相关的操作。

从字面意思看,initApplicationEventMulticaster方法就是初始化一些广播器。通过之前的分析。在onRefresh方法之前的都是对beanFactory工厂的一些辅助。那么这里的init也应该是初始化beanFactory中的广播器。那么怎么初始化?那么应该和之前的beanPostProcessors是一样的,都需要通过beanDefinitionMap解析再获取实例化bean然后进行注册。

既然如此猜想,那就让我们走进看看吧!

protected void initApplicationEventMulticaster() {  //获取beanFactory工厂    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    //是否已经存在    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {      //如果存在的话就拿到赋值       this.applicationEventMulticaster =          beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);      if (logger.isTraceEnabled()) {        logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");      }    }    else {    //新创建一个,然后注册到beanFactory中      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);      if (logger.isTraceEnabled()) {        logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +            "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");      }    }  }

我们看到这里也是直接创建一个SimpleApplicationEventMulticaster然后直接扔进IOC容器中并自己保留一份。

那么我们看看这里的SimpleApplicationEventMulticaster是何方神圣。

看到这里有线程工具和ErrorHandler,除此之外,还有很多方法比如doInvoke等。显然这里的类具有的作用就是执行。上边只是注册这个bean,那么后边肯定会有执行。那么这里的执行都是怎么执行的,还有他执行的条件是什么。

@Override  public void multicastEvent(ApplicationEvent event) {    multicastEvent(event, resolveDefaultEventType(event));  }      @Override  public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));    //获取所有的监听器    for (final ApplicationListener
listener : getApplicationListeners(event, type)) {      //拿到线程池执 Executor executor = getTaskExecutor(); if (executor != null) {        //广播实践 executor.execute(() -> invokeListener(listener, event)); } else { //广播 invokeListener(listener, event); } } }   //获取application类的实体 protected Collection
> getApplicationListeners( ApplicationEvent event, ResolvableType eventType) { Object source = event.getSource(); Class
sourceType = (source != null ? source.getClass() : null); ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);    //从initApplicationEventMulticaster注册的retrieverMux中获取 ListenerRetriever retriever = this.retrieverCache.get(cacheKey); if (retriever != null) { //获取相关额监听器并返回 return retriever.getApplicationListeners(); } if (this.beanClassLoader == null || (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) && (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {      // 加锁,retrievalMutex是beanFactory中的单例bean缓存。显然这块也是在onRefresh之后执行的 synchronized (this.retrievalMutex) { retriever = this.retrieverCache.get(cacheKey); if (retriever != null) {        //拿到需要的Listner return retriever.getApplicationListeners(); } retriever = new ListenerRetriever(true); Collection
> listeners = retrieveApplicationListeners(eventType, sourceType, retriever); this.retrieverCache.put(cacheKey, retriever); return listeners; } } else { // No ListenerRetriever caching -> no synchronization necessary return retrieveApplicationListeners(eventType, sourceType, null); }  } 

通过跟踪,发现这里的监听器的添加是在onrefresh之后的reginsterlistners方法中。

//注册监听器  protected void registerListeners() {    // 获取监听器    for (ApplicationListener
listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener);    }    //从beanfactories中获取监听器 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) {      //添加到content中的属性中 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); }    //拿到earlyApplicationEvents Set
earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { //广播消息 getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }

通过上述分析,initApplicationEventMulticaster其实只是做了简单的初始化。并没有相关的功能实现。具体的广播事件其实是在IOC启动中调度的。注意这里是ApplicationListener接口的类。也就是这里获取都是实现了ApplicationListener接口的类。也就是说如果我们实现了ApplicationListener接口,然后调用multicastEvent方法就可以将我们的事件广播出去。但是这里multicastEvent谁可以调?我们看一下content的继承关系图谱。

发现有一个ApplicationEventPublisher,这是一个事件发布器。其中两个方法均为发布事件的。

我们看一下它的实现类。发现这里是有调用的。也就是说只要拿到了content,就可以将消息发布出去进行广播。

总结:在initApplicationEventMulticaster方法中,spring其实就是只是初始化了一个广播的中间类并放到ioc中并在自己哪里留存引用。真正向其中添加广播监听器是在onRefresh之后的registerListeners方法。而真正触发multicastEvent的方式是在content中调用publishEvent方法。 

转载地址:http://zhkmi.baihongyu.com/

你可能感兴趣的文章
《redis in action》redis发布订阅
查看>>
《redis in action》sort排序命令
查看>>
《redis in action》redis事务
查看>>
《redis in action》key的自动过期
查看>>
《redis in action》redis持久化简介
查看>>
Oracle RAC Failover 详解
查看>>
批处理 自动修改 IP 地址
查看>>
Oracle RAC LoadBalance
查看>>
v$sql,v$sqlarea,v$sqltext 和 v$sql_plan 说明
查看>>
ORA-31623 When Submitting a Datapump Job [ID 308388.1]
查看>>
Oracle SYSAUX 表空间 说明
查看>>
RAC 安装patch 后启动实例 报错 ORA-00439 feature not enabled- Real Application Clusters 解决方法
查看>>
On RAC, expdp Removes the Service Name [ID 1269319.1]
查看>>
Important Changes to Oracle Database Patch Sets Starting With 11.2.0.2 [ID 1189783.1]
查看>>
Oracle RAC 平台下 Patch 安装与卸载 步骤
查看>>
Oracle Database 11gR1 和 10gR2 ASM Best Practices 说明文档
查看>>
ASM Concepts Quick Overview [ID 1086199.1]
查看>>
PowerDesigner 业务处理模型( BPM ) 说明
查看>>
PowerDesigner 企业架构模型 ( EAM ) 说明
查看>>
PowerDesigner 正向工程 和 逆向工程 说明
查看>>