0%

BeanDefinition属性

Spring BeanDefinition 详解:Bean 的 “元数据蓝图”

BeanDefinition 是 Spring 中描述 Bean 的核心元数据接口,它像一份 “蓝图”,定义了 Bean 的创建规则、属性配置、依赖关系等关键信息。Spring 容器正是基于这些元数据完成 Bean 的实例化、属性注入和生命周期管理。本文将从接口定义、核心属性、实现类体系三个维度,全面解析 BeanDefinition 的设计与作用。

BeanDefinition 核心接口:定义 Bean 的元数据规范

BeanDefinition 接口继承了 AttributeAccessor(属性访问)和 BeanMetadataElement(元数据元素)接口,为 Bean 定义了一套完整的元数据规范。其核心作用是 “描述 Bean 的所有特征,让 Spring 容器知道如何创建和管理这个 Bean”。

核心属性分类

BeanDefinition 的属性可分为基础配置依赖关系生命周期角色标识四大类,对应 XML 配置中的<bean>标签属性或注解配置的元信息:

类别 核心属性 对应 XML 配置示例
基础配置 类名(beanClassName)、作用域(scope)、是否抽象(abstract) <bean class="com.User" scope="singleton" abstract="false"/>
依赖关系 父 Bean(parentName)、依赖 Bean(dependsOn)、工厂 Bean(factoryBeanName) <bean parent="baseBean" depends-on="dataSource" factory-bean="userFactory"/>
生命周期 懒加载(lazyInit)、初始化方法(initMethodName)、销毁方法(destroyMethodName) <bean lazy-init="true" init-method="init" destroy-method="close"/>
装配规则 自动装配候选(autowireCandidate)、首选 Bean(primary) <bean autowire-candidate="true" primary="true"/>
角色标识 角色(role):区分用户定义 Bean 和 Spring 内部 Bean -

关键方法解析

(1)作用域相关
1
2
3
4
5
6
7
8
// 设置作用域(singleton/prototype等)
void setScope(String scope);
// 获取作用域
String getScope();
// 判断是否为单例(简化方法,等价于 scope == SCOPE_SINGLETON)
boolean isSingleton();
// 判断是否为原型(简化方法,等价于 scope == SCOPE_PROTOTYPE)
boolean isPrototype();
  • 单例(SCOPE_SINGLETON):容器中仅存在一个实例,默认值;
  • 原型(SCOPE_PROTOTYPE):每次getBean()都创建新实例。
(2)依赖与继承相关
1
2
3
4
5
6
7
// 设置父Bean名称(实现Bean配置继承)
void setParentName(String parentName);
String getParentName();

// 设置依赖的Bean(被依赖Bean优先初始化)
void setDependsOn(String... dependsOn);
String[] getDependsOn();
  • 父 Bean 继承:子 Bean 可继承父 Bean 的属性配置(如<bean id="child" parent="parent"/>);
  • 依赖顺序:dependsOn指定的 Bean 会在当前 Bean 之前初始化,解决非直接依赖的初始化顺序问题。
(3)工厂方法相关
1
2
3
4
5
6
7
// 设置工厂Bean名称(通过实例工厂创建Bean时使用)
void setFactoryBeanName(String factoryBeanName);
String getFactoryBeanName();

// 设置工厂方法名称(静态工厂或实例工厂的方法)
void setFactoryMethodName(String factoryMethodName);
String getFactoryMethodName();
  • 示例:<bean id="user" factory-bean="userFactory" factory-method="createUser"/>
(4)属性与构造方法参数
1
2
3
4
5
// 获取构造方法参数(对应<constructor-arg>标签)
ConstructorArgumentValues getConstructorArgumentValues();

// 获取普通属性(对应<property>标签)
MutablePropertyValues getPropertyValues();

这两个方法返回的对象存储了 Bean 的属性注入信息,是属性填充(populateBean)的核心数据来源。

(5)角色标识
1
2
3
// 设置Bean角色(区分用户Bean和Spring内部Bean)
void setRole(int role);
int getRole();
  • ROLE_APPLICATION(0):用户定义的 Bean(如业务 Service);
  • ROLE_SUPPORT(1):支撑性 Bean(如配置类的辅助 Bean);
  • ROLE_INFRASTRUCTURE(2):Spring 内部 Bean(如BeanPostProcessor实现类)。

BeanDefinition 实现类体系:从抽象到具体

BeanDefinition 有多个实现类,构成了一套完整的体系,分别对应不同场景(XML 配置、注解配置、父子继承等)。

1. 抽象基类:AbstractBeanDefinition

AbstractBeanDefinition 是所有实现类的抽象父类,实现了 BeanDefinition 接口的大部分方法,并增加了更多细化属性(如自动装配模式、方法覆盖等)。

核心扩展属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition {
// 自动装配模式(no/byName/byType/constructor)
private int autowireMode = AUTOWIRE_NO;
// 方法覆盖(用于lookup-method和replaced-method标签)
private MethodOverrides methodOverrides = new MethodOverrides();
// 初始化方法名称
private String initMethodName;
// 销毁方法名称
private String destroyMethodName;
// 是否强制执行初始化/销毁方法
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
// 是否为合成Bean(如AOP代理对象)
private boolean synthetic = false;
}
  • 自动装配模式:对应 XML 的autowire属性,如autowire="byType"表示按类型自动注入;
  • 方法覆盖:支持通过lookup-method动态替换方法返回值,或通过replaced-method替换方法实现(AOP 的基础技术之一)。

2. 核心实现类

(1)RootBeanDefinition:顶级 Bean 定义

RootBeanDefinition 是最常用的实现类,代表一个 “独立的、非继承的 Bean 定义”,可直接用于创建 Bean 实例。

  • 适用场景:XML 中定义的独立<bean>标签、@Bean注解定义的 Bean;
  • 特点:包含完整的 Bean 元数据,不依赖其他 BeanDefinition。
(2)ChildBeanDefinition:继承式 Bean 定义

ChildBeanDefinition 必须依赖父 BeanDefinition,可继承父定义的属性并添加自定义配置。

1
2
3
4
// 示例:创建子BeanDefinition
ChildBeanDefinition childDef = new ChildBeanDefinition("parentBean");
childDef.setBeanClassName("com.ChildUser");
childDef.getPropertyValues().add("name", "child");
  • 对应 XML:<bean id="child" parent="parentBean" class="com.ChildUser">
  • 注意:Spring 2.5 后推荐使用GenericBeanDefinition替代,更灵活。
(3)GenericBeanDefinition:通用灵活的 Bean 定义

GenericBeanDefinition 是 Spring 2.5 引入的实现类,兼具RootBeanDefinitionChildBeanDefinition的功能,支持动态设置父 BeanDefinition。

1
2
3
4
// 示例:动态设置父Bean
GenericBeanDefinition genericDef = new GenericBeanDefinition();
genericDef.setParentName("parentBean"); // 可动态修改父Bean
genericDef.setBeanClassName("com.GenericUser");
  • 优势:相比ChildBeanDefinition,父 Bean 名称可动态修改,更适合编程式定义 Bean;
  • 适用场景:注解驱动的配置、动态注册 Bean(如@Component扫描生成的 BeanDefinition)。
(4)AnnotatedBeanDefinition:注解驱动的 Bean 定义

AnnotatedBeanDefinition 是接口,专为注解配置的 Bean 设计,增加了获取注解元数据的方法:

1
2
3
4
5
6
public interface AnnotatedBeanDefinition extends BeanDefinition {
// 获取类级别的注解元数据
AnnotationMetadata getMetadata();
// 获取工厂方法的注解元数据(若为@Bean方法)
MethodMetadata getFactoryMethodMetadata();
}

其实现类 AnnotatedGenericBeanDefinition 常用于:

  • @Configuration 注解的配置类;
  • @Component 及其派生注解(@Service@Repository等)标注的类;
  • @Bean 注解的方法定义的 Bean。

示例:@Service 标注的类会被解析为 AnnotatedGenericBeanDefinition,通过getMetadata()可获取@Service的属性(如value)。

BeanDefinition 的生命周期:从创建到使用

BeanDefinition 的生命周期贯穿 Spring 容器初始化的全流程,关键节点如下:

  1. 创建
    • XML 配置:XmlBeanDefinitionReader 解析<bean>标签生成 RootBeanDefinition
    • 注解配置:ClassPathBeanDefinitionScanner 扫描@Component类生成 AnnotatedGenericBeanDefinition
    • 编程式注册:通过BeanDefinitionRegistry手动注册 GenericBeanDefinition
  2. 注册
    • 所有 BeanDefinition 被注册到BeanDefinitionRegistry(如DefaultListableBeanFactorybeanDefinitionMap)。
  3. 增强
    • BeanFactoryPostProcessor 对 BeanDefinition 进行修改(如PropertySourcesPlaceholderConfigurer替换${}占位符)。
  4. 使用
    • Spring 容器基于 BeanDefinition 的元信息,通过createBean()方法实例化 Bean、注入属性、执行初始化。
  5. 缓存
    • 单例 Bean 的 BeanDefinition 会被长期缓存,原型 Bean 的 BeanDefinition 在每次实例化时复用。

实践意义:为什么需要理解 BeanDefinition?

  1. 排查 Bean 创建问题
    • 若 Bean 未被实例化,可检查是否存在对应的 BeanDefinition;
    • 若属性注入失败,可查看 BeanDefinition 的propertyValues是否正确。
  2. 扩展 Spring 功能
    • 自定义BeanFactoryPostProcessor修改 BeanDefinition(如动态添加属性);
    • 编程式注册 BeanDefinition(如根据配置动态创建 Bean)。
  3. 理解 Spring 核心机制
    • AOP、事务管理等功能本质是通过修改 BeanDefinition(如添加代理信息)实现的;
    • 注解驱动的自动配置(如@Autowired)依赖AnnotatedBeanDefinition的元数据解析。

总结

BeanDefinition 是 Spring IOC 容器的 “数据核心”,它将 XML、注解等配置形式统一转化为容器可识别的元数据,为 Bean 的创建提供了完整的 “施工图纸”。其核心实现类(RootBeanDefinitionGenericBeanDefinitionAnnotatedGenericBeanDefinition)分别对应不同配置场景,而AbstractBeanDefinition则统一了基础属性和行为

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10