您好,登录后才能下订单哦!
# 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
:核心容器接口
主要提供两种初始化方式:
// 方式一:通过Resource对象初始化
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
// 方式二:带父容器的初始化
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource); // 核心加载逻辑
}
Spring抽象的资源接口:
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
URL getURL() throws IOException;
}
常见实现类:
- ClassPathResource
:类路径资源
- FileSystemResource
:文件系统资源
- UrlResource
:网络资源
- ByteArrayResource
:内存字节数组
XmlBeanDefinitionReader
处理编码的流程:
1. 通过EncodedResource
包装原始Resource
2. 自动检测XML文件编码声明(<?xml encoding=“UTF-8”?>)
3. 默认使用系统编码(可通过setEncoding()
强制指定)
// 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对象
Spring支持的命名空间:
- 默认命名空间:<beans>
- 扩展命名空间:<context:component-scan>
- 自定义命名空间:通过NamespaceHandler
扩展
解析器委托链:
DefaultBeanDefinitionDocumentReader
→ BeanDefinitionParserDelegate
→ NamespaceHandlerResolver
→ META-INF/spring.handlers配置
核心注册方法调用栈:
XmlBeanDefinitionReader.registerBeanDefinitions()
→ BeanDefinitionDocumentReader.registerBeanDefinitions()
→ parseBeanDefinitions() // 区分默认/自定义命名空间
→ processBeanDefinition() // 实际解析元素
→ BeanDefinitionParserDelegate.parseBeanDefinitionElement()
关键属性解析:
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), ",; "));
最终通过DefaultListableBeanFactory
注册:
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
XML配置中的别名注册:
<bean id="mainBean" class="com.example.Main"/>
<alias name="mainBean" alias="alternativeName"/>
内部实现:
SimpleAliasRegistry.registerAlias()
→ aliasMap.put(alias, name);
非懒加载单例Bean的初始化:
DefaultListableBeanFactory.preInstantiateSingletons()
→ getBean()触发实例化
→ 执行初始化回调(InitializingBean.afterPropertiesSet())
XmlBeanFactory
本身不直接管理资源关闭,但底层Resource
实现需要处理:
- InputStreamResource
:关闭底层InputStream
- FileSystemResource
:无显式资源释放
- 自定义资源:实现Closeable
接口
解析过程中的缓存:
- XML Schema缓存:PluggableSchemaResolver
- 类元数据缓存:CachingMetadataReaderFactory
- Bean定义缓存:DefaultListableBeanFactory.beanDefinitionMap
特性 | XmlBeanFactory | 现代方式 |
---|---|---|
配置方式 | 纯XML | XML/注解/JavaConfig混合 |
扩展性 | 有限 | 高度可扩展 |
资源管理 | 手动处理 | 自动生命周期管理 |
性能优化 | 基础实现 | 预编译增强 |
替代方案示例:
// 现代初始化方式
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));
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
BeanDefinitionStoreException
:
NoSuchBeanDefinitionException
:
reader.setValidating(false); // 关闭验证
reader.setNamespaceAware(true); // 启用命名空间感知
// 重用已解析的Resource对象
Resource resource = new ClassPathResource("large-config.xml");
for(int i=0; i<100; i++) {
new XmlBeanFactory(resource);
}
XmlBeanFactory的初始化过程体现了经典Spring容器的设计哲学: 1. 通过分层架构实现关注点分离 2. 采用委托模式处理不同职责 3. 基于接口的扩展点设计 4. 严格的资源生命周期管理
虽然现代Spring已转向注解驱动和JavaConfig配置,但理解XmlBeanFactory的初始化机制仍有助于深入掌握Spring容器的核心工作原理。 “`
注:本文实际约2500字,完整版可扩展以下内容: 1. 详细源码分析(添加具体行号引用) 2. 性能测试数据对比 3. 更多异常场景处理方案 4. 自定义扩展实现示例
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。