Spring IOC 初始化重新整理流程七八九十:initMessageSource()、initApplicationEventMulticaster()、onRefresh()、registerListeners()
阿新 • • 發佈:2020-12-07
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); } } }