Skip to content

BeanDefinition源码分析

一、BeanDefinition的核心定位:Bean的"元数据蓝图"

在Spring IOC容器中,BeanDefinition是描述Bean的所有元数据的对象,相当于Bean的"设计图纸"。容器通过它来了解:

  • Bean的类型(class);
  • Bean的作用域(scope,如singleton/prototype);
  • Bean的生命周期(初始化/销毁方法、延迟加载);
  • Bean的依赖关系(构造器参数、属性值、依赖的Bean);
  • Bean的扩展配置(方法覆盖、自动装配模式、工厂方法等)。

简单来说:Bean = BeanDefinition + 容器的实例化逻辑。容器启动时,先加载所有BeanDefinition,再根据其描述创建Bean实例。

二、BeanDefinition的接口体系

Spring通过接口分层定义了BeanDefinition的核心能力,其继承关系如下:

BeanDefinition
├─ AbstractBeanDefinition(抽象实现,核心基类)
   ├─ RootBeanDefinition(顶层BeanDefinition,无父类)
   ├─ ChildBeanDefinition(子类BeanDefinition,必须有父类)
   └─ GenericBeanDefinition(Spring 2.5+推荐,替代Root/Child,支持动态父类)
└─ AnnotatedBeanDefinition(扩展接口,支持注解元数据,如@Component/@Bean)
   └─ ScannedGenericBeanDefinition(扫描@Component注解生成的BeanDefinition)
   └─ ConfigurationClassBeanDefinition(@Configuration类中的@Bean方法生成的BeanDefinition)

1. 核心接口:BeanDefinition

org.springframework.beans.factory.config.BeanDefinition定义了Bean元数据的最小集,关键方法如下:

java
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    // 作用域相关
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    // Bean角色(用于区分用户定义的Bean和框架内部Bean)
    int ROLE_APPLICATION = 0; // 用户应用Bean
    int ROLE_SUPPORT = 1;     // 框架支持Bean(如ApplicationContext内部Bean)
    int ROLE_INFRASTRUCTURE = 2; // 框架基础设施Bean(如BeanPostProcessor)
    
    // 设置/获取Bean的类名(注意:是类的全限定名,而非Class对象)
    void setBeanClassName(String beanClassName);
    String getBeanClassName();
    
    // 设置/获取作用域(默认singleton)
    void setScope(String scope);
    String getScope();
    
    // 设置/获取延迟加载(默认false,即容器启动时创建singleton Bean)
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();
    
    // 设置/获取依赖的Bean名称(依赖的Bean必须先初始化)
    void setDependsOn(String... dependsOn);
    String[] getDependsOn();
    
    // 设置/获取是否自动装配到其他Bean(默认false)
    void setAutowireCandidate(boolean autowireCandidate);
    boolean isAutowireCandidate();
    
    // 设置/获取是否为主要Bean(当多个Bean满足自动装配条件时,优先选择主要Bean)
    void setPrimary(boolean primary);
    boolean isPrimary();
    
    // 设置/获取工厂Bean名称(如果当前Bean是通过工厂Bean创建的)
    void setFactoryBeanName(String factoryBeanName);
    String getFactoryBeanName();
    
    // 设置/获取工厂方法名称(如果当前Bean是通过工厂方法创建的)
    void setFactoryMethodName(String factoryMethodName);
    String getFactoryMethodName();
    
    // 获取构造器参数(用于构造器注入)
    ConstructorArgumentValues getConstructorArgumentValues();
    
    // 获取属性值(用于setter注入)
    MutablePropertyValues getPropertyValues();
    
    // 设置/获取初始化方法名称(如init-method="init")
    void setInitMethodName(String initMethodName);
    String getInitMethodName();
    
    // 设置/获取销毁方法名称(如destroy-method="destroy")
    void setDestroyMethodName(String destroyMethodName);
    String getDestroyMethodName();
    
    // 设置/获取Bean角色
    void setRole(int role);
    int getRole();
    
    // 设置/获取描述信息(用于日志或错误提示)
    void setDescription(String description);
    String getDescription();
}

2. 抽象基类:AbstractBeanDefinition

org.springframework.beans.factory.support.AbstractBeanDefinition所有具体BeanDefinition的基类,实现了BeanDefinition的核心逻辑,并扩展了更多属性(如自动装配模式、方法覆盖、BeanClass缓存等)。其关键属性如下:

java
public abstract class AbstractBeanDefinition implements BeanDefinition, Cloneable {
    // 自动装配模式(默认NO,即不自动装配)
    public static final int AUTOWIRE_NO = 0; // 不自动装配
    public static final int AUTOWIRE_BY_NAME = 1; // 按名称自动装配(属性名匹配Bean名称)
    public static final int AUTOWIRE_BY_TYPE = 2; // 按类型自动装配(属性类型匹配Bean类型)
    public static final int AUTOWIRE_CONSTRUCTOR = 3; // 按构造器自动装配(构造器参数类型匹配Bean类型)
    public static final int AUTOWIRE_AUTODETECT = 4; // 自动检测(已过时,Spring 3.0+移除)
    
    // 依赖检查模式(默认NONE,即不检查)
    public static final int DEPENDENCY_CHECK_NONE = 0; // 不检查
    public static final int DEPENDENCY_CHECK_OBJECTS = 1; // 检查对象类型依赖
    public static final int DEPENDENCY_CHECK_SIMPLE = 2; // 检查简单类型依赖(如int、String)
    public static final int DEPENDENCY_CHECK_ALL = 3; // 检查所有类型依赖
    
    // 核心属性
    private volatile Class<?> beanClass; // Bean的Class对象(延迟解析,避免提前加载类)
    private String scope = SCOPE_SINGLETON; // 作用域(默认singleton)
    private boolean lazyInit = false; // 延迟加载(默认false)
    private int autowireMode = AUTOWIRE_NO; // 自动装配模式(默认不自动装配)
    private int dependencyCheck = DEPENDENCY_CHECK_NONE; // 依赖检查模式(默认不检查)
    private String[] dependsOn; // 依赖的Bean名称
    private String factoryBeanName; // 工厂Bean名称
    private String factoryMethodName; // 工厂方法名称
    private ConstructorArgumentValues constructorArgumentValues; // 构造器参数
    private MutablePropertyValues propertyValues; // 属性值(setter注入)
    private MethodOverrides methodOverrides; // 方法覆盖(如lookup-method、replace-method)
    private String initMethodName; // 初始化方法名称
    private String destroyMethodName; // 销毁方法名称
    private boolean enforceInitMethod = true; // 是否强制调用初始化方法(默认true)
    private boolean enforceDestroyMethod = true; // 是否强制调用销毁方法(默认true)
    private boolean synthetic = false; // 是否为合成Bean(框架生成的,非用户定义)
    private int role = ROLE_APPLICATION; // Bean角色(默认用户应用Bean)
    private String description; // 描述信息
    private Resource resource; // 定义Bean的资源(如XML文件、类文件)
}

3. 具体实现类

  • RootBeanDefinition顶层BeanDefinition,无父类,是合并后的最终BeanDefinition(如子BeanDefinition合并父类后生成RootBeanDefinition)。
  • ChildBeanDefinition子类BeanDefinition,必须指定父BeanDefinition(parentName),用于继承父类的配置(如属性、作用域)。Spring 2.5+已被GenericBeanDefinition替代
  • GenericBeanDefinition推荐的通用实现,支持动态设置父BeanDefinition(setParentName),灵活性更高。例如:
    java
    GenericBeanDefinition gbd = new GenericBeanDefinition();
    gbd.setBeanClassName("com.example.User");
    gbd.setParentName("parentBean"); // 动态指定父Bean
    gbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  • AnnotatedBeanDefinition支持注解元数据的扩展接口,其实现类如ScannedGenericBeanDefinition(扫描@Component注解生成)、ConfigurationClassBeanDefinition(@Configuration类中的@Bean方法生成),用于保存注解信息(如@Scope、@Lazy)。

三、BeanDefinition的生命周期:从解析到使用

BeanDefinition的生命周期贯穿Spring容器初始化的全流程,关键步骤如下:解析(Parse)→ 注册(Register)→ 合并(Merge)→ 使用(Instantiate)

1. 解析:从配置到BeanDefinition

Spring支持多种配置方式(XML、注解、JavaConfig),解析过程的核心是将配置信息转换为BeanDefinition

(1)XML配置解析

<bean>标签为例,Spring通过XmlBeanDefinitionReader读取XML文件,再通过BeanDefinitionParserDelegate处理每个<bean>标签,生成对应的BeanDefinition。
示例XML

xml
<bean id="user" class="com.example.User" scope="prototype" lazy-init="true">
    <property name="name" value="张三"/>
    <property name="age" value="25"/>
    <constructor-arg index="0" value="李四"/>
    <depends-on="address"/>
</bean>

解析过程

  • BeanDefinitionParserDelegate会创建一个GenericBeanDefinition
  • 设置beanClassNamecom.example.User
  • 设置scopeprototype
  • 设置lazyInittrue
  • <property>标签转换为MutablePropertyValues(存储name=张三age=25);
  • <constructor-arg>标签转换为ConstructorArgumentValues(存储构造器参数李四);
  • 设置dependsOnaddress(依赖address Bean)。

(2)注解配置解析

@Component注解为例,Spring通过ClassPathScanningCandidateComponentProvider扫描指定包,找到带@Component注解的类,生成ScannedGenericBeanDefinition
示例类

java
@Component
@Scope("prototype")
@Lazy(true)
public class User {
    @Value("张三")
    private String name;
    @Value("25")
    private int age;
}

解析过程

  • 扫描到User类,创建ScannedGenericBeanDefinition
  • 设置beanClassNamecom.example.User
  • @Scope注解获取scopeprototype
  • @Lazy注解获取lazyInittrue
  • @Value注解获取属性值,转换为MutablePropertyValues(存储name=张三age=25)。

(3)JavaConfig解析

@Configuration@Bean注解为例,Spring通过ConfigurationClassPostProcessor(BeanFactoryPostProcessor)处理@Configuration类,将@Bean方法转换为ConfigurationClassBeanDefinition
示例类

java
@Configuration
public class AppConfig {
    @Bean
    @Scope("prototype")
    @Lazy(true)
    public User user() {
        User user = new User();
        user.setName("张三");
        user.setAge(25);
        return user;
    }
}

解析过程

  • ConfigurationClassPostProcessor扫描到AppConfig类,处理@Bean方法user()
  • 创建ConfigurationClassBeanDefinition,设置beanClassNamecom.example.User
  • @Scope注解获取scopeprototype
  • @Lazy注解获取lazyInittrue
  • user()方法的返回值作为Bean实例(通过工厂方法创建)。

2. 注册:将BeanDefinition存入容器

解析生成的BeanDefinition会被注册到BeanDefinitionRegistry(BeanDefinition的注册中心)。BeanDefinitionRegistry是一个接口,其核心实现是DefaultListableBeanFactory(Spring默认的BeanFactory),它通过beanDefinitionMapMap<String, BeanDefinition>)存储所有BeanDefinition。
注册过程示例

java
// 1. 创建BeanFactory(默认是DefaultListableBeanFactory)
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 2. 创建BeanDefinition(以GenericBeanDefinition为例)
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClassName("com.example.User");
gbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
gbd.getPropertyValues().add("name", "张三");

// 3. 注册BeanDefinition到BeanFactory
beanFactory.registerBeanDefinition("user", gbd);

注意:注册时会检查beanName是否重复,若重复且allowBeanDefinitionOverriding(默认true)为true,则覆盖旧的BeanDefinition。

3. 合并:处理父BeanDefinition

当BeanDefinition有父类(如ChildBeanDefinitionGenericBeanDefinition指定了parentName)时,Spring会合并父类和子类的配置,生成RootBeanDefinition(最终用于实例化的BeanDefinition)。
合并逻辑

  • 子类的属性会覆盖父类的同名属性(如子类设置了scope=prototype,父类设置了scope=singleton,则子类的scope生效);
  • 父类的propertyValuesconstructorArgumentValues合并到子类(子类未设置的属性用父类的);
  • 父类的methodOverridesdependsOn等配置会合并到子类
    示例
java
// 父BeanDefinition(singleton,name=父类)
GenericBeanDefinition parentGbd = new GenericBeanDefinition();
parentGbd.setBeanClassName("com.example.User");
parentGbd.setScope(BeanDefinition.SCOPE_SINGLETON);
parentGbd.getPropertyValues().add("name", "父类");

// 子类BeanDefinition(prototype,name=子类,父类=parentGbd)
GenericBeanDefinition childGbd = new GenericBeanDefinition();
childGbd.setParentName("parentGbd");
childGbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
childGbd.getPropertyValues().add("age", 25);

// 合并子类和父类,生成RootBeanDefinition
RootBeanDefinition mergedRbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition("childGbd");

// 合并后的结果:
// scope=prototype(子类覆盖父类)
// propertyValues={name=父类, age=25}(父类和子类合并)

4. 使用:根据BeanDefinition实例化Bean

容器启动时(或第一次获取Bean时,若lazyInit=true),Spring会根据合并后的RootBeanDefinition实例化Bean,流程如下:

  1. 实例化:通过反射或工厂方法创建Bean实例(如User user = new User());
  2. 属性注入:将propertyValues中的属性值注入到Bean实例(如user.setName("张三"));
  3. 初始化:调用初始化方法(如init-methodInitializingBean.afterPropertiesSet());
  4. 缓存:若scope=singleton,将Bean实例存入singletonObjects缓存(Map<String, Object>);
  5. 销毁:当容器关闭时(若scope=singleton),调用销毁方法(如destroy-methodDisposableBean.destroy())。

四、BeanDefinition的扩展:后置处理与动态修改

Spring提供了BeanFactoryPostProcessor接口,允许在BeanDefinition注册后、Bean实例化前修改BeanDefinition的元数据。这是Spring框架的核心扩展点之一。

1. 示例:修改属性值

java
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 获取名为"user"的BeanDefinition
        BeanDefinition userBD = beanFactory.getBeanDefinition("user");
        // 修改属性值(将name从"张三"改为"李四")
        userBD.getPropertyValues().add("name", "李四");
        // 修改作用域(从prototype改为singleton)
        userBD.setScope(BeanDefinition.SCOPE_SINGLETON);
    }
}

2. 示例:动态注册BeanDefinition

java
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 动态创建BeanDefinition(User类)
        GenericBeanDefinition gbd = new GenericBeanDefinition();
        gbd.setBeanClassName("com.example.User");
        gbd.getPropertyValues().add("name", "动态注册");
        // 注册到容器
        registry.registerBeanDefinition("dynamicUser", gbd);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 可选:修改已有的BeanDefinition
    }
}

五、总结:BeanDefinition的核心价值

BeanDefinition是Spring IOC容器的核心元数据模型,其价值在于:

  1. 分离配置与实现:将Bean的配置(如类名、属性、作用域)与实现(类的代码)分离,提高灵活性;
  2. 支持多种配置方式:XML、注解、JavaConfig都能转换为BeanDefinition,统一容器的处理逻辑;
  3. 扩展能力:通过BeanFactoryPostProcessor可以动态修改BeanDefinition,满足复杂需求;
  4. 生命周期管理:容器通过BeanDefinition控制Bean的实例化、初始化、销毁过程,实现依赖注入、AOP等核心功能。

六、源码阅读建议

若要深入理解BeanDefinition的源码,建议从以下类入手:

  1. BeanDefinition接口org.springframework.beans.factory.config.BeanDefinition(核心方法);
  2. AbstractBeanDefinitionorg.springframework.beans.factory.support.AbstractBeanDefinition(核心属性与实现);
  3. GenericBeanDefinitionorg.springframework.beans.factory.support.GenericBeanDefinition(通用实现);
  4. BeanDefinitionRegistryorg.springframework.beans.factory.support.BeanDefinitionRegistry(注册中心接口);
  5. DefaultListableBeanFactoryorg.springframework.beans.factory.support.DefaultListableBeanFactory(BeanFactory的默认实现,存储BeanDefinition的beanDefinitionMap);
  6. XmlBeanDefinitionReaderorg.springframework.beans.factory.xml.XmlBeanDefinitionReader(XML配置解析);
  7. ClassPathScanningCandidateComponentProviderorg.springframework.context.annotation.ClassPathScanningCandidateComponentProvider(注解扫描解析)。

通过以上分析,相信你对Spring的BeanDefinition有了更深入的理解。BeanDefinition是Spring框架的"基石",掌握它能帮助你更好地理解Spring IOC容器的工作机制,以及扩展Spring框架的能力。