1. 配置信息的加載
Enviroment對象:負(fù)責(zé)加載系統(tǒng)的配置信息





new StandardEnvironment()會調(diào)到父類的構(gòu)造方法中

父類的構(gòu)造方法會調(diào)到自己實(shí)現(xiàn)的customizePropertySources()



至此enviroment已經(jīng)把系統(tǒng)的配置信息讀到了內(nèi)部的PropertySource中
本地配置信息加載
需要在application.xml中配置這樣的自定義標(biāo)簽,來指定要加載的配置文件

那么,在spring容器解析xml文件的時候,就會解析到這個標(biāo)簽

解析context:property-placeholder標(biāo)簽
先根據(jù)標(biāo)簽頭獲取到一個鏈接

再根據(jù)鏈接從spring.handlers文件找到對應(yīng)的處理器

找的時候會先調(diào)用Handler的init方法初始化內(nèi)部的解析器,每種冒號后面的屬性都會對應(yīng)一個解析器,比如componetScan,property-placeholder

最終都放在內(nèi)部從父類NamespaceHandlerSupport繼承而來的parses容器中,是個key-value的map


找到了這個類ContextNamespaceHandler

接下來調(diào)用這個類的parse方法,這里會先從內(nèi)部的解析器容器中找到合適的解析器

這里獲取到的是PropertyPlaceholderBeanDefinitionParser這個類

調(diào)用 PropertyPlaceholderBeanDefinitionParser 的parse方法
這部分的代碼稍微有點(diǎn)繞,要么調(diào)父類的方法,父類的方法中又回調(diào)子類的重寫的方法
先看繼承圖

首先調(diào)用父類AbstractBeanDefinitionParser的parse

方法體中有調(diào)用了下面一級父類的parseInternal方法,這個方法其實(shí)就是構(gòu)建了一個BeanDefinition對象

其中需要注意的點(diǎn)就是這個BD對象的beanClass由子類解析器返回

可以看到,返回了一個PropertySourcesPlaceholderConfigurer類型,這個類型的bean后面再講是干嘛的
構(gòu)建BD對象的過程中又調(diào)用到了子類解析器的parseInternal的doParse方法,其實(shí)就是對BD對象的一些屬性進(jìn)行填充,這里最重要的標(biāo)簽中的location屬性,表明要解析那個配置文件

parseInternal方法最終得到一個完成的Bd,parse方法在后面對這個類型為PropertySourcesPlaceholderConfigurer的BD注冊到容器中,這就說明后續(xù)這個類型的bean會被實(shí)例化。

PropertySourcesPlaceholderConfigurer類
從類圖中看看這個bean和普通的bean是否一樣

可以看到這個類實(shí)現(xiàn)了一個很重要的接口BeanFactoryPostProcessor,那么他會比在普通的bean解析成BD之后,實(shí)例化之前進(jìn)行實(shí)例化,并被容器調(diào)用到他的postProcessBeanFactory方法

- 將enviorment對象放到propertySources中
- 解析本地配置文件,放到propertySources中

該方法后面還會調(diào)用processProperties方法,將創(chuàng)建的StringValueResolver匿名對象,。該對象實(shí)現(xiàn)resolveStringValue方法,將調(diào)用propertyResolver(持有enviroment / 本地配置信息 的propertySource)來處理


