上一篇: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
中每一個方法的源碼。