1. 程式人生 > 其它 >12.spring原始碼之屬性檔案解析

12.spring原始碼之屬性檔案解析

講到這裡,refresh()中核心方法就剩下finishBeanBactoryInitialization()方法沒講,這個方法主要是Bean的例項化、依賴注入、AOP,在講這個方法之前我們講一些其他的知道,如屬性檔案解析、如果沒有配置檔案,那麼BeanDefinition怎麼來的,Bean的例項化是依賴於BeanDefinition,今天就講一講屬性檔案的解析。

1.進入ContextNamespaceHandler類

我們知道context標籤的handler是ContextNamespaceHandler,在是這個類的init()方法完成對各個具體標籤的註冊,property-placeholder屬性檔案解析對應的處理類是PropertyPlaceholderBeanDefinitionParser.。

2.進入PropertyPlaceholderBeanDefinitionParser類

具體的解析其實交給PropertySourcePlaceholderConfigurer這個類來完成的,這個類是一個BeanFactoryPostProcessor介面的一個實現,在前面講過,對實現了BeanFactoryPostProcessor介面的類會呼叫它的postProcessorBeanFactory()方法,而屬性檔案的解析就是在這個方法中完成的

3.PropertySourcePlaceholderConfigurer類的postProcessorBeanFactory()方法

這個方法就是把Environment和屬性檔案中key、value放入Properties物件,然後把Properties物件封裝成PropertySource物件,然後加入到MutablePropertySource的list容器中

把屬性檔案中key、value放入Properties物件在mergeProperties()方法中

4.進入processProperties()方法

5.進入doprocessProperties()方法

6.進入visitBeanDefinition()方法

除了屬性值可以配置在屬性配置檔案中,類、工廠方法名等都可以。以PropertyValue為例

7.進入visitPropertyValues()方法

8.進入resolveValue()方法

9.進入rsolverStringValue()方法

10.進入replacePlaceholder()方法

11.進入parseStringValue()方法,真正的解析是在這個方法完成的

resolverPlaceholder()方法其實就是從Properties物件中根據key拿到value值,placeholder就是${}的key值

最終都是通過getProperty()方法根據Key從Properties中獲取value值。像Environment,在最開始的postProcessorBeanFactory()方法中處理Environment的時候就重寫了getProperty()方法,就是從environment根據Key獲取value值

12.回到第4步中,我們看一下@Value註解的解析

StringValueResolver這個介面中只有一個resolveStringValue()方法,呼叫這個方法就會走這個lambda表示式的程式碼,在第5步的時候把解析器放入了一個容器中,在依賴注入解析@Value的時候就會從容器中拿到這個解析器,呼叫resolveStringValue()方法,然後就會執行這個lambda表示式的內容,完成@value的解析,從屬性檔案中獲取value值,完成依賴注入。

其實也是一樣呼叫getProperty()方法

再看replacePlaceholders()方法,最終也會走到parseStringValue這個方法