1. 程式人生 > 實用技巧 >Spring IOC 初始化重新整理流程七八九十:initMessageSource()、initApplicationEventMulticaster()、onRefresh()、registerListeners()

Spring IOC 初始化重新整理流程七八九十:initMessageSource()、initApplicationEventMulticaster()、onRefresh()、registerListeners()

Spring IOC 初始化重新整理流程:https://www.cnblogs.com/jhxxb/p/13609289.html

方法原始碼

initMessageSource()

初始化訊息源,向容器裡註冊一個事件源的單例 Bean:MessageSource

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory 
= getBeanFactory(); // 判斷是否已經存在名為 “messageSource” 的 Bean 了(一般情況下是沒有的) if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { // 從容器裡拿出這個 messageSource this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource.
// 設定父屬性 if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource registered already.
hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); // 其實就是獲取到父容器的 messageSource 欄位(否則就是 getParent() 上下文自己) dms.setParentMessageSource(getInternalParentMessageSource()); // 給當前的 messageSource 賦值 this.messageSource = dms; // 把 messageSource 作為一個單例的 Bean 註冊進 beanFactory 工廠裡 beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }

initApplicationEventMulticaster()

初始化事件多播器:ApplicationEventMulticaster

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 若使用者自己定義了這個 Bean(名稱必須是 "applicationEventMulticaster"),就以使用者的為準。
        // 否則註冊一個系統預設的 SimpleApplicationEventMulticaster
        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 {
            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() + "]");
            }
        }
    }

onRefresh()

public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {
    @Override
    protected void onRefresh() {
        // 模版方法。本環境中的實現為:AbstractRefreshableWebApplicationContext#onRefresh 方法,Web 環境,所以去初始化了它的主題
        this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }

registerListeners()

上面已經把事件源、多播器都註冊好了,這裡就是註冊監聽器了

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    protected void registerListeners() {
        // Register statically specified listeners first.
        // 這一步和手動註冊 BeanDefinitionRegistryPostProcessor 一樣,可以自己通過 set 手動註冊監聽器,然後是最先執行的(此處我們沒有自己set)
        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!
        // 取到容器裡面的所有的監聽器的名稱,繫結到廣播器,後面會廣播出去這些事件
        // 注意:此處並沒有說到 ApplicationListenerDetector
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        // 這一步需要注意:如果存在早期應用事件,這裡就直接釋出了(同時就把 earlyApplicationEvents 欄位置為 null)
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }