溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

XmlBeanFactory如何初始化

發布時間:2021-07-30 14:26:33 來源:億速云 閱讀:129 作者:Leah 欄目:大數據
# XmlBeanFactory如何初始化

## 1. 引言

XmlBeanFactory是Spring框架早期版本中用于加載和解析XML配置的核心類(Spring 3.x后已標記為`@Deprecated`,推薦使用`DefaultListableBeanFactory`+`XmlBeanDefinitionReader`替代)。本文將深入剖析其初始化過程,涵蓋以下關鍵環節:

1. 類繼承體系分析
2. 核心構造方法解析
3. XML配置加載機制
4. Bean定義注冊流程
5. 資源關閉與清理機制

## 2. 類繼承體系

```java
public class XmlBeanFactory extends DefaultListableBeanFactory {
    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    //...
}

關鍵繼承關系: - DefaultListableBeanFactory:完整的BeanFactory實現 - AbstractAutowireCapableBeanFactory:實現Bean創建/依賴注入 - AbstractBeanFactory:基礎Bean定義管理 - BeanFactory:核心容器接口

3. 初始化過程詳解

3.1 構造方法入口

主要提供兩種初始化方式:

// 方式一:通過Resource對象初始化
public XmlBeanFactory(Resource resource) throws BeansException {
    this(resource, null);
}

// 方式二:帶父容器的初始化
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) {
    super(parentBeanFactory);
    this.reader.loadBeanDefinitions(resource); // 核心加載邏輯
}

3.2 資源加載階段

3.2.1 Resource體系

Spring抽象的資源接口:

public interface Resource extends InputStreamSource {
    boolean exists();
    boolean isReadable();
    boolean isOpen();
    URL getURL() throws IOException;
}

常見實現類: - ClassPathResource:類路徑資源 - FileSystemResource:文件系統資源 - UrlResource:網絡資源 - ByteArrayResource:內存字節數組

3.2.2 編碼處理

XmlBeanDefinitionReader處理編碼的流程: 1. 通過EncodedResource包裝原始Resource 2. 自動檢測XML文件編碼聲明(<?xml encoding=“UTF-8”?>) 3. 默認使用系統編碼(可通過setEncoding()強制指定)

3.3 XML解析過程

3.3.1 Document加載

// XmlBeanDefinitionReader.java
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) {
    Document doc = doLoadDocument(inputSource, resource);
    return registerBeanDefinitions(doc, resource);
}

使用DocumentLoader接口默認實現:

DefaultDocumentLoader.loadDocument() 
    → EntityResolver處理DTD/XSD
    → SAX解析生成Document對象

3.3.2 命名空間處理

Spring支持的命名空間: - 默認命名空間:<beans> - 擴展命名空間:<context:component-scan> - 自定義命名空間:通過NamespaceHandler擴展

解析器委托鏈:

DefaultBeanDefinitionDocumentReader
    → BeanDefinitionParserDelegate
        → NamespaceHandlerResolver
            → META-INF/spring.handlers配置

3.4 Bean定義注冊

核心注冊方法調用棧:

XmlBeanDefinitionReader.registerBeanDefinitions()
    → BeanDefinitionDocumentReader.registerBeanDefinitions()
        → parseBeanDefinitions() // 區分默認/自定義命名空間
            → processBeanDefinition() // 實際解析元素
                → BeanDefinitionParserDelegate.parseBeanDefinitionElement()

3.4.1 BeanDefinition構建

關鍵屬性解析:

AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
    parent, className, classLoader);

// 解析屬性
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
bd.setLazyInit(Boolean.valueOf(ele.getAttribute(LAZY_INIT_ATTRIBUTE)));
bd.setDependsOn(StringUtils.tokenizeToStringArray(
    ele.getAttribute(DEPENDS_ON_ATTRIBUTE), ",; "));

3.4.2 注冊到容器

最終通過DefaultListableBeanFactory注冊:

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

4. 初始化后處理

4.1 別名處理

XML配置中的別名注冊:

<bean id="mainBean" class="com.example.Main"/>
<alias name="mainBean" alias="alternativeName"/>

內部實現:

SimpleAliasRegistry.registerAlias()
    → aliasMap.put(alias, name);

4.2 預實例化單例

非懶加載單例Bean的初始化:

DefaultListableBeanFactory.preInstantiateSingletons()
    → getBean()觸發實例化
    → 執行初始化回調(InitializingBean.afterPropertiesSet())

5. 資源清理機制

5.1 資源釋放

XmlBeanFactory本身不直接管理資源關閉,但底層Resource實現需要處理: - InputStreamResource:關閉底層InputStream - FileSystemResource:無顯式資源釋放 - 自定義資源:實現Closeable接口

5.2 緩存清理

解析過程中的緩存: - XML Schema緩存:PluggableSchemaResolver - 類元數據緩存:CachingMetadataReaderFactory - Bean定義緩存:DefaultListableBeanFactory.beanDefinitionMap

6. 與現代容器的對比

6.1 廢棄原因

特性 XmlBeanFactory 現代方式
配置方式 純XML XML/注解/JavaConfig混合
擴展性 有限 高度可擴展
資源管理 手動處理 自動生命周期管理
性能優化 基礎實現 預編譯增強

6.2 遷移建議

替代方案示例:

// 現代初始化方式
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));

7. 初始化流程圖解

sequenceDiagram
    participant Client
    participant XmlBeanFactory
    participant XmlBeanDefinitionReader
    participant Resource
    participant DocumentLoader
    
    Client->>XmlBeanFactory: 構造器傳入Resource
    XmlBeanFactory->>XmlBeanDefinitionReader: 委托加載
    XmlBeanDefinitionReader->>Resource: 獲取InputStream
    Resource-->>XmlBeanDefinitionReader: 返回輸入流
    XmlBeanDefinitionReader->>DocumentLoader: 加載Document
    DocumentLoader-->>XmlBeanDefinitionReader: 返回DOM樹
    XmlBeanDefinitionReader->>XmlBeanDefinitionReader: 解析Bean定義
    XmlBeanDefinitionReader->>XmlBeanFactory: 注冊BeanDefinition

8. 典型問題排查

8.1 常見異常

  1. BeanDefinitionStoreException

    • 原因:XML格式錯誤/資源不可讀
    • 解決:檢查XML語法和文件權限
  2. NoSuchBeanDefinitionException

    • 原因:Bean名稱拼寫錯誤/未掃描到
    • 解決:檢查beanName和組件掃描路徑

8.2 性能優化

  1. 預編譯模式:
reader.setValidating(false); // 關閉驗證
reader.setNamespaceAware(true); // 啟用命名空間感知
  1. 資源緩存:
// 重用已解析的Resource對象
Resource resource = new ClassPathResource("large-config.xml");
for(int i=0; i<100; i++) {
    new XmlBeanFactory(resource); 
}

9. 總結

XmlBeanFactory的初始化過程體現了經典Spring容器的設計哲學: 1. 通過分層架構實現關注點分離 2. 采用委托模式處理不同職責 3. 基于接口的擴展點設計 4. 嚴格的資源生命周期管理

雖然現代Spring已轉向注解驅動和JavaConfig配置,但理解XmlBeanFactory的初始化機制仍有助于深入掌握Spring容器的核心工作原理。 “`

注:本文實際約2500字,完整版可擴展以下內容: 1. 詳細源碼分析(添加具體行號引用) 2. 性能測試數據對比 3. 更多異常場景處理方案 4. 自定義擴展實現示例

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女