Spring 框架中的 spring-beans 模块是 Spring IoC(控制反转)容器的核心组成部分,负责 Bean 的解析、定义、创建和管理。下面从解析的角度详细说明。
一、核心概念
1. Bean 定义解析的主要角色
-
BeanDefinition:Bean 的元数据描述(类名、作用域、生命周期、属性依赖等)
-
BeanDefinitionReader:读取配置(XML、注解、Java Config)并注册 BeanDefinition
-
BeanDefinitionRegistry:BeanDefinition 的注册中心(通常是 DefaultListableBeanFactory)
-
BeanFactoryPostProcessor:允许在 Bean 实例化前修改 BeanDefinition
二、XML 配置解析流程
典型配置
XML
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="userService" class="com.example.UserService">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
解析步骤
-
资源加载 :
ResourceLoader加载 XML 资源 -
文档解析 :
XmlBeanDefinitionReader使用 DOM/SAX 解析 XML -
Bean 注册 :解析
<bean>元素生成GenericBeanDefinition,注册到BeanDefinitionRegistry
关键代码位置
java
// XmlBeanDefinitionReader 核心方法
public int loadBeanDefinitions(Resource resource) {
// 1. 获取 XML 的 Document 对象
Document doc = this.documentLoader.loadDocument(...);
// 2. 注册 Bean 定义
return registerBeanDefinitions(doc, resource);
}
// DefaultBeanDefinitionDocumentReader
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 遍历 <beans> 下的子元素
if (delegate.isDefaultNamespace(root)) {
for (Element ele : root.getChildNodes()) {
if (ele.getNodeName().equals("bean")) {
processBeanDefinition(ele, delegate);
}
}
}
}
三、注解配置解析流程
常用注解
-
@Component,@Service,@Repository,@Controller -
@Autowired,@Value,@Qualifier
解析方式
java
// 方式1:使用 AnnotationConfigApplicationContext
new AnnotationConfigApplicationContext(AppConfig.class);
// 方式2:组件扫描
@ComponentScan(basePackages = "com.example")
public class AppConfig { }
// 解析核心类
// ClassPathBeanDefinitionScanner
// AnnotatedBeanDefinitionReader
内部处理
java
// ClassPathBeanDefinitionScanner 扫描包
public int scan(String... basePackages) {
// 1. 查找候选 Bean(根据 @Component 元注解)
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
// 2. 注册 BeanDefinition(解析 @Scope, @Lazy 等)
for (BeanDefinition candidate : candidates) {
registerBeanDefinition(candidate);
}
}
四、BeanDefinition 合并解析
当存在父子 <bean> 定义时:
java
<bean id="parent" abstract="true">
<property name="commonProp" value="common"/>
</bean>
<bean id="child" parent="parent" class="com.example.Child">
<property name="childProp" value="child"/>
</bean>
Spring 会调用 getMergedBeanDefinition() 将父子定义合并 成一个完整的 RootBeanDefinition。
五、解析过程中的扩展点
1. BeanFactoryPostProcessor
java
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition bd = beanFactory.getBeanDefinition("userService");
bd.setScope("prototype"); // 修改作用域
}
}
2. BeanDefinitionRegistryPostProcessor
优先于普通 BeanFactoryPostProcessor,可注册新的 BeanDefinition。
3. 自定义 XML 标签解析
java
// 实现 NamespaceHandler 和 BeanDefinitionParser
// 在 META-INF/spring.handlers 中注册
六、流程图总结
bash
配置文件 (XML/注解/JavaConfig)
↓
BeanDefinitionReader 加载
↓
解析生成 BeanDefinition (元数据)
↓
注册到 BeanDefinitionRegistry
↓
BeanFactoryPostProcessor 处理 (修改 BeanDefinition)
↓
完成解析,容器持有 BeanDefinition 集合
↓
后续用于 Bean 实例化 (getBean 时或预实例化)
七、关键类总结
| 类名 | 职责 |
|---|---|
BeanDefinition |
存储 Bean 的元信息 |
BeanDefinitionReader |
从配置源读取并注册 BeanDefinition |
BeanDefinitionRegistry |
管理 BeanDefinition 的容器 |
BeanDefinitionParserDelegate |
解析 XML 中的 <bean> 元素 |
ClassPathBeanDefinitionScanner |
扫描类路径下的注解 Bean |
ConfigurationClassPostProcessor |
核心注解配置解析器(处理 @Configuration, @Bean 等) |
spring-beans 的解析本质:将配置声明 转换为内存中的 BeanDefinition 对象,为后续的依赖注入和生命周期管理做好准备。理解解析过程有助于掌握 Spring 容器启动的全貌,以及在需要时自定义 Bean 的加载行为。