深入理解Spring的容器内事件发布监听机制(6)

其实看到这里会有一个疑问,registerListeners()方法只是找到了所���监听器的beanName并将其保存到了事件发布器ApplicationEventMulticaster中,那么真正的事件监听器实例是何时被创建并被加入到事件发布器中的?
这里我们不得不退回到启动容器的refresh()方法中,在初始化beanFactory之后,初始化事件发布器之前,容器在prepareBeanFactory(beanFactory)方法中又注册了一些重要组件,其中就包括一个特殊的BeanPostProcessor:ApplicationListenerDetector,正如其类名暗示的那样,这是一个事件监听器的探测器。

深入理解Spring的容器内事件发布监听机制

深入理解Spring的容器内事件发布监听机制

该类实现了BeanPostProcessor接口,如下图所示

深入理解Spring的容器内事件发布监听机制

ApplicationListenerDetector实现了BeanPostProcessor接口,可以在容器级别对所有bean的生命周期过程进行增强。这里主要是为了能够在初始化所有bean后识别出所有的事件监听器bean并
将其注册到事件发布器中

@Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {

//判断该bean是否实现了ApplicationListener接口
        if (this.applicationContext != null && bean instanceof ApplicationListener) {
            // potentially not detected as a listener by getBeanNamesForType retrieval
            Boolean flag = this.singletonNames.get(beanName);
            if (Boolean.TRUE.equals(flag)) {
                // singleton bean (top-level or inner): register on the fly
                //将实现了ApplicationListener接口的bean注册到事件发布器applicationEventMulticaster中
                this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
            }
            else if (Boolean.FALSE.equals(flag)) {
                if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
                    // inner bean with other scope - can't reliably process events
                    logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
                            "but is not reachable for event multicasting by its containing ApplicationContext " +
                            "because it does not have singleton scope. Only top-level listener beans are allowed " +
                            "to be of non-singleton scope.");
                }
                this.singletonNames.remove(beanName);
            }
        }
        return bean;
    }

在初始化所有的bean后,该ApplicationListenerDetector的postProcessAfterInitialization(Object bean, String beanName)方法会被作用在每一个bean上,通过判断传入的bean
是否是ApplicationListener实例进行过滤,然后将找到的事件监听器bean注册到事件发布器中。

3.4 容器事件发布流程

深入理解Spring的容器内事件发布监听机制

深入理解Spring的容器内事件发布监听机制

这里为了简化源码阅读的工作量,对一些细节和分支情形做了忽略,只考虑主流程,如上图箭头所示,这里调用了事件发布器的multicastEvent()方法进行事件发布,需要传入事件event和事件类型
eventType作为参数。不过通常这个eventType参数为null,因为事件的类型信息完全可以通过反射的方式从event对象中获得。继续跟进源码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8aa7eccef7a6ee573b4af64ab1388374.html