SpringApplicationRunListener 事件体系 与观察者模式

image.png

在Spring Boot 初始化中讲过,完成SpringApplication构造后,调用run方法,会进行SpringApplicationRunListener的初始化,通过debug得到一个默认SpringApplicationRunListener 实现

查看源代码 (构造函数)

    public EventPublishingRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
          // 实例化了一个  SimpleApplicationEventMulticaster 

        this.initialMulticaster = new SimpleApplicationEventMulticaster();

  //     并将 SpringApplication中的监听器全部放到了  SimpleApplicationEventMulticaster  中
        for (ApplicationListener<?> listener : application.getListeners()) {
            this.initialMulticaster.addApplicationListener(listener);
        }
    }

这里看下 SimpleApplicationEventMulticaster 的继承关系
image.png

事件体系

  • ApplicationEvent(事件)
  • ApplicationListener(消息接收者)
  • ApplicationEventMulticaster (消息广播)

事件体系的初始化

在SpringApplication的refreshContext 中进行,具体代码在AbstractApplicationContext.refresh()代码块见如下,调用initApplicationEventMulticaster()来完成事件体系的搭建

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
               this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } 

beanFactory 用户可以在自定义广播事件,Spring 会将其设置为 自身的 事件广播,没有发现自定义的广播,会使用默认的 SimpleApplicationEventMulticaster

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

// 事件注册

    protected void registerListeners() {
        // Register statically specified listeners first.
            //  注册指定的Bean
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!

// 实际调用 DefaultListableBeanFactory 中 getBeanNamesForType得到自定义的 ApplicationListenerbean进行事件注册
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 广播早期的事件
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

广播事件

    protected void publishEvent(Object event, ResolvableType eventType) {

    ...
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    // 省略代码
       ...  
    }

广播事件通过调用 ApplicationEventMulticaster的 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) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {
                invokeListener(listener, event);
            }
        }
    }
  invokeListener的核心代码   listener.onApplicationEvent(event);

遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法。

代码中看到 应用到了 Executor 有可用的executor 会使用并发的模式执行事件,SimpleApplicationEventMulticaster内,并没有实现线程池,所以使用同步的方式执行事件,需要异步配置的,需要去实现线程池。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值