beandefinition是spring中描述bean配置元数据的核心接口,定义“如何创建、装配和管理bean”,包含类信息、作用域、懒加载、依赖关系、初始化/销毁方法、属性值、构造参数等关键元数据,并统一抽象xml、@bean、@component等配置来源。

BeanDefinition 是 Spring 框架中描述 Bean 配置元数据的核心接口,它不直接定义 Bean 实例,而是**定义“如何创建、装配和管理一个 Bean”**——包括类信息、作用域、是否懒加载、依赖关系、初始化/销毁方法、属性值、构造参数等全部配置细节。
BeanDefinition 描述了哪些关键元数据
它把 XML 配置、@Bean 注解、@Component 扫描等不同来源的声明,统一抽象为可编程操作的对象。主要包含:
- beanClass:实际要实例化的 Class(如 UserService.class),或工厂类 + 工厂方法名(用于 FactoryBean 或 @Bean 方法)
- scope:作用域字符串("singleton"、"prototype"、"request" 等),决定容器如何缓存和复用实例
- lazyInit:是否延迟初始化(true 表示首次 getBean 时才创建)
- dependsOn:显式依赖的其他 bean 名称列表(确保它们先于当前 bean 初始化)
- autowireMode:自动装配模式(NO / BY_NAME / BY_TYPE / CONSTRUCTOR / AUTODETECT)
- constructorArgumentValues:构造函数参数(支持类型匹配、索引定位、引用其他 bean 或字面量)
- propertyValues:setter 属性赋值集合(如 name="username" value="admin" 或 ref="dataSource")
- initMethodName / destroyMethodName:生命周期回调方法名(如 init() / cleanup())
- isAbstract / isSingleton / isPrototype:便捷布尔访问器,由底层字段派生
常见来源如何生成 BeanDefinition
Spring 在启动阶段将各类配置“翻译”为 BeanDefinition,并注册到 BeanFactory 中:
-
XML 配置:解析
标签,逐个构建 GenericBeanDefinition 实例 - @Bean 方法:通过 ConfigurationClassPostProcessor 解析 @Configuration 类,为每个 @Bean 方法生成 RootBeanDefinition,封装方法反射信息和参数依赖
- @Component 及衍生注解:ClassPathBeanDefinitionScanner 扫描 classpath,对带 @Component 的类创建 ScannedGenericBeanDefinition,保留注解元数据供后续处理(如 @Scope、@Lazy)
开发者能怎么操作 BeanDefinition
多数情况无需手动创建,但可通过扩展点定制行为:
- 实现 BeanFactoryPostProcessor(如 PropertySourcesPlaceholderConfigurer),在所有 BeanDefinition 加载后、实例化前修改其属性(如替换 ${} 占位符)
- 实现 BeanDefinitionRegistryPostProcessor,在 BeanDefinition 注册阶段介入,动态注册、移除或替换定义(常用于条件化注册、AOP 增强代理定义注入)
- 继承 GenericBeanDefinition 或使用 RootBeanDefinition 构造器,手动生成定义并注册(测试或插件场景较常见)
- 通过 BeanDefinitionBuilder 流式构建定义,比直接 new 更安全(自动处理父子继承、作用域校验等)
注意几个易混淆点
- BeanDefinition ≠ Bean 实例:它只是“配方”,getBean() 才真正执行实例化逻辑
- 子类关系重要:GenericBeanDefinition 适用于大多数场景;RootBeanDefinition 是合并后的最终定义(处理了 @Primary、@Profile 等条件);AnnotatedGenericBeanDefinition 特化支持注解元数据读取
- “合并”(merged)概念:当存在父 BeanDefinition 时(XML 中 parent 属性),Spring 会合并出一个 RootBeanDefinition 用于创建实例,原始定义仍保留
- @Scope("prototype") 不影响 BeanDefinition 本身,只影响后续 getBean() 调用时是否复用已有实例
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











