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內,並沒有實現線程池,所以使用同步的方式執行事件,需要異步配置的,需要去實現線程池。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章