Spring事件机制源码的详细分析

本篇文章给大家带来的内容是关于Spring事件机制源码的详细分析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

前言:由于之前使用Spring事件机制出现了问题,所以特意去了解这块的源码。Spring事件机制其实就是事件发布/订阅(注意在Spring中订阅指的是监听)。

PS:Spring版本为5.1.5.RELEASE

源码分析

初始化

初始化这块关键是核心组件的注册

1、ApplicationEventPublisher的初始化与注册,关键方法为AbstractApplicationContext的方法prepareBeanFactory()

2、ApplicationEventMulticaster的初始化与注册,关键方法为AbstractApplicationContext的initApplicationEventMulticaster()方法

3、ApplicationListener的初始化与注册,关键方法为AbstractApplicationContext的registerListeners()方法

这块不细说,感兴趣的可以自行跟踪关键方法

事件发布/订阅

事件发布/订阅的关键方法为AbstractApplicationContext的publishEvent,源码如下:

    protected void publishEvent(Object event, ResolvableType eventType) {
        // 避免空指针
        Assert.notNull(event, Event must not be null);
        if (logger.isTraceEnabled()) {
            logger.trace(Publishing event in  + getDisplayName() + :  + event);
        }

        // 处理event对象,将其转换为ApplicationEvent
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<Object>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
            }
        }

        // 是否延迟多播,即将事件发布到所有监听器中
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            //此处为事件监听处理器的调用关键
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // 是否将事件发布到父容器中
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

通过代码跟踪,发现Spring中使用ApplicationEventMulticaster的默认实现SimpleApplicationEventMulticaster来触发事件的监听,关键方法为multicastEvent()方法,源码如下:

    @Override
    public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
        // 获取事件类型
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//依次遍历事件监听器
            // 获取线程池
            Executor executor = getTaskExecutor();
            if (executor != null) {//线程池不为null,则异步调用监听器
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {// 同步调用监听器
                invokeListener(listener, event);
            }
        }
    }

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注编程之家的Java视频教程栏目!

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...