7-Spring容器創建之refresh(1)——概覽

上一篇:Spring容器創建(3)——register註冊配置類

上一篇我們講到執行完register()方法,

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		// 1. 首先初始化Spring的7個內置Bean後置處理器,並放到 DefaultListableBeanFactory 類型的對象 beanFactory 中
		// 2. 創建Spring的註解解析器 Component
		this();
		// 傳入的配置類annotatedClasses,生成BeanDefinition,然後將BeanDefinition註冊到DefaultListableBeanFactory 類型的對象 beanFactory 中
		register(annotatedClasses);
		// 刷新容器
		refresh();
	}

下面我們來進入到Spring非常重要的環節,進入refresh()方法。

1. refresh

在進入refresh()方法之前,我們先看看AnnotationConfigApplicationContext類的類結構

在這裏插入圖片描述

ApplicationContext接口有12個實現類和一個子接口,這麼多實現類中只有AbstractApplicationConext類中實現了refresh方法,其他子類沒有重寫該方法。因此,我們debug的時候會直接跳到到AbstractApplicationConext中。

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 容器刷新前的預處理工作,初始化一些屬性的設置:context、驗證一些屬性信息
			prepareRefresh();

			//  獲取一個新的beanFactory(經過this()和register()處理的beanFactory),並給beanFactory設置Id。
			// obtainFreshBeanFactory()返回的beanFactory類型是DefaultListableBeanFactory,ConfigurableListableBeanFactory 是DefaultListableBeanFactory的接口
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 對beanFactory進行一些設置:設置類加載器、支持表達式解析器、添加BeanPostProcessor等
			prepareBeanFactory(beanFactory);

			try {
				// BeanFactory準備工作完成後進行的後置處理工作
				// 子類(比如web的ApplicationContext)通過重寫這個方法來再BeanFactory創建並預準備完成後做進一步的設置,默認爲空方法。.
				postProcessBeanFactory(beanFactory);

				// 解析@Configuration、@Component,@ComponentScan,@Import,@ImportResource等註解,將@Configuration註解對應的類註冊到beanFactory中
				invokeBeanFactoryPostProcessors(beanFactory);

				// 註冊beanFactory中擴展了BeanPostProcessor的bean.
				// AutowiredAnnotationBeanPostProcessor(處理被@Autowired註解修飾的bean並注入)
				// RequiredAnnotationBeanPostProcessor(處理被@Required註解修飾的方法)
				//CommonAnnotationBeanPostProcessor(處理@PreDestroy、@PostConstruct、@Resource等多個註解的作用)等。
				registerBeanPostProcessors(beanFactory);

				// 初始化MessageSource組件(做消息綁定、消息解析)
				initMessageSource();

				// 初始化事件派發器.
				initApplicationEventMulticaster();

				// 在容器刷新的時候可以自定義邏輯(子類自己去實現邏輯).
				onRefresh();

				// 給容器中所有項目裏面的ApplicationListener 註冊進來
				registerListeners();

				// 初始化所有剩下的非懶加載的單實例Bean
				// 實例化的過程各種BeanPostProcessor開始起作用
				finishBeanFactoryInitialization(beanFactory);

				// 清除上下文資源緩存,發佈ContextRefreshedEvent事件告知對應的ApplicationListener進行響應的操作
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

以上就是refresh方法的整體流程,代碼很清晰,一共有12個步驟,其中有三個步驟是非常重要的:

  • invokeBeanFactoryPostProcessors(beanFactory);
  • registerBeanPostProcessors(beanFactory);
  • finishBeanFactoryInitialization(beanFactory);

接下來,會具體的分析refresh中每一個方法的源碼。

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