XmlBeanFactory如何初始化

发布时间:2021-07-30 14:26:33 作者:Leah
来源:亿速云 阅读:125
# 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. 自定义扩展实现示例

推荐阅读:
  1. 初始化脚本
  2. informix 初始化

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

xmlbeanfactory

上一篇:docker中dockerfile语法如何使用

下一篇:Android中如何实现移动端页面强制竖屏

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》