1. 程式人生 > >《spring原始碼解讀》 - IoC 之解析 import 標籤

《spring原始碼解讀》 - IoC 之解析 import 標籤

![spring-framework.jpg](https://img2020.cnblogs.com/other/2024393/202009/2024393-20200902154305425-1091612735.jpg) 在上一文中我們分析了註冊 `BeanDefinition` 的過程,在其中我們瞭解到在解析跟節點和子節點時分兩種情況,對於預設名稱空間的標籤我們通過 `DefaultBeanDefinitionDocumentReader#parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)` 進行處理,而對於自定義標籤則通過 `BeanDefinitionParserDelegate#parseCustomElement(Element ele)` 方法進行處理。

這裡我們首先對預設名稱空間的解析進行開始解讀, `#parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)` 方法的程式碼如下: ``` java public static final String NESTED_BEANS_ELEMENT = "beans"; public static final String ALIAS_ELEMENT = "alias"; public static final String NAME_ATTRIBUTE = "name"; public static final String ALIAS_ATTRIBUTE = "alias"; public static final String IMPORT_ELEMENT = "import"; /** * 如果根節點或者子節點採用預設名稱空間的話 採用預設的解析方式 * @param ele * @param delegate */ private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { // import 標籤 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { //alias 標籤 processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { //處理 bean 標籤 這是spring中很核心的標籤處理 processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 處理 beans 標籤 doRegisterBeanDefinitions(ele); } } ``` * 通過上述程式碼我們可以的看到預設標籤包含 `import` 、 `alias` 、 `bean` 、 `beans` , 本文將對 `import` 的解析進行解讀
## 1. Import 案例 經歷過 `Spring` 配置檔案的小夥伴都知道,如果工程比較大,配置檔案的維護會讓人覺得恐怖,檔案太多了,想象將所有的配置都放在一個 `spring.xml` 配置檔案中,哪種後怕感是不是很明顯?
所有針對這種情況 `Spring` 提供了一個分模組的思路,利用 `import` 標籤,例如我們可以構造一個這樣的 `spring.xml` 。
``` java ``` > `spring.xml` 配置檔案中,使用 `import` 標籤的方式匯入其他模組的配置檔案。 * 如果有配置需要修改直接修改相應配置檔案即可。 * 若有新的模組需要引入直接增加 `import` 即可。 > 這樣大大簡化了配置後期維護的複雜度,同時也易於管理。 ## 2. importBeanDefinitionResource `DefaultBeanDefinitionDocumentReader#parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)` 方法使用者解析 `import` 標籤,方法程式碼如下: ``` java protected void importBeanDefinitionResource(Element ele) { // 1.獲取 節點 屬性resource的值 String location = ele.getAttribute(RESOURCE_ATTRIBUTE); //2. 判斷是否為空,為空直接返回 if (!StringUtils.hasText(location)) { getReaderContext().error("Resource location must not be empty", ele); return; } //3.解析 系統屬性 ${user.dir} // Resolve system properties: e.g. "${user.dir}" location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location); // 實際 Resource 集合, 即 import 的地址