Spring基本執行過程解析
一。基本過程
1.當建立一個上下文:
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-config.xml");
2.進入ClassPathXmlApplicationContext.java
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent);//2-1 setConfigLocations(configLocations);//2-2 if (refresh) { refresh();//2-3 } }
2-1 :解析super(parent)
主要功能是獲取 ResourcePatternResolver
經過層層呼叫,在AbstractApplicationContext.java中:
this.resourcePatternResolver = getResourcePatternResolver();
getResourcePatternResolver經過檢視為:
new PathMatchingResourcePatternResolver(this);
結論:主要作用是設定applicationContext物件的resourcePatternResolver 屬性為new PathMatchingResourcePatternResolver(this)
2-2 :setConfigLocations(configLocations)
替換配置檔名稱中的佔位符
2-3 :見下一節 refresh()詳解
二。refresh()詳解
進入AbstractApplicationContext # refresh()
synchronized (this.startupShutdownMonitor) { // 1 prepareRefresh(); // 2 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3 prepareBeanFactory(beanFactory); try { // 4 postProcessBeanFactory(beanFactory); // 5 invokeBeanFactoryPostProcessors(beanFactory); // 6 registerBeanPostProcessors(beanFactory); // 7 initMessageSource(); // 8 initApplicationEventMulticaster(); // 9 onRefresh(); // 10 registerListeners(); // 11 finishBeanFactoryInitialization(beanFactory); // 12 finishRefresh(); } catch (BeansException ex) { 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; } }
1、prepareRefresh()
進入此方法,可以看到兩個比較重要的步驟
initPropertySources(); //初始化屬性源,比如從properties檔案中讀取,從url讀取....這個方法一般交給子類實現
getEnvironment().validateRequiredProperties(); //驗證資源中的佔位符是否在必要的屬性源中都存在,若不存在則丟擲異 常MissingRequiredPropertiesException
2.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
進入方法 ,比較重要的一段為↓
refreshBeanFactory(); //*****初始化beanDefinitionMap---->載入xml中的<bean>為beanDefinition
此時可以 看到alreadyCreated屬性數量小於beanDefinitionMap長度
3.prepareBeanFactory(beanFactory);
初始化這個上下文中beanFactory的一些特性
4.postProcessBeanFactory(beanFactory);
對這個beanFactory進行後處理,由子類實現
5.invokeBeanFactoryPostProcessors(beanFactory);
呼叫beanFactory的處理器(如果有的話)
BeanFactoryPostProcessor介面實現類可以在當前BeanFactory初始化後,bean例項化之前對BeanFactory做一些處理
註解處理器:可以載入beanDefinitionMap()
SpringBoot中:讀取屬性處理器:讀取property檔案到Enviroment中
SpringBoot中:
6.registerBeanPostProcessors(beanFactory);
如果BeanPostProcessors介面的某個實現類被註冊到某個容器,那麼該容器的每個受管Bean在呼叫初始化方法之前,都會獲得該介面實現類的一個回撥
7.initMessageSource(); 國際化使用
8.initApplicationEventMulticaster(); //初始化上下文 監聽廣播器
9.onRefresh();
//初始化一些特殊的bean
10.registerListeners();
11 finishBeanFactoryInitialization(beanFactory);
//初始化其他的bean
可以檢視alreadyCreated
12 finishRefresh();