深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质

深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质

 

Spring 的核心之一是对 Bean 的管理,而 `BeanDefinition` 是 Spring 中定义和描述 Bean 信息的关键接口。通过深入了解 `BeanDefinition` 及其相关实现类,我们可以更好地理解 Spring 容器如何管理 Bean 的生命周期和依赖注入过程。

 

1. BeanDefinition 的概述

 

`BeanDefinition` 是 Spring 框架中一个重要的接口,它定义了 Bean 的所有属性,包括:

 

- Bean 的类名

- 作用域(如单例或原型)

- 初始化方法和销毁方法

- 构造函数参数

- 属性值

 

`BeanDefinition` 是 Spring IOC 容器用来描述 Bean 元数据的基本单位。

 

2. BeanDefinition 的层次结构

 

`BeanDefinition` 接口有多个子接口和实现类,主要包括:

 

- **RootBeanDefinition**: 代表一个标准的、可实例化的 Bean 定义。

- **ChildBeanDefinition**: 代表一个 Bean 定义,它从父定义中继承配置。

- **GenericBeanDefinition**: 一个通用的 Bean 定义实现,通常用于通过编程方式注册 Bean。

- **AbstractBeanDefinition**: 提供了 `BeanDefinition` 接口的基础实现,是多个具体实现类的父类。

 

3. BeanDefinition 接口源码

 

以下是 `BeanDefinition` 接口的简化版源码:

 

```java
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
 
    // 常量定义,如 SCOPE_SINGLETON 和 SCOPE_PROTOTYPE
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
 
    // 获取和设置 Bean 的类名
    @Nullable
    String getBeanClassName();
    void setBeanClassName(@Nullable String beanClassName);
 
    // 获取和设置 Bean 的作用域
    @Nullable
    String getScope();
    void setScope(@Nullable String scope);
 
    // 判断是否为单例或原型
    boolean isSingleton();
    boolean isPrototype();
 
    // 获取和设置初始化方法和销毁方法
    @Nullable
    String getInitMethodName();
    void setInitMethodName(@Nullable String initMethodName);
 
    @Nullable
    String getDestroyMethodName();
    void setDestroyMethodName(@Nullable String destroyMethodName);
 
    // 获取和设置构造函数参数和值
    ConstructorArgumentValues getConstructorArgumentValues();
    MutablePropertyValues getPropertyValues();
 
    // 克隆当前 BeanDefinition 对象
    BeanDefinition cloneBeanDefinition();
}
```

 

4. AbstractBeanDefinition 类

 

`AbstractBeanDefinition` 是 `BeanDefinition` 接口的抽象实现,提供了大部分通用属性的存储和操作方法。以下是 `AbstractBeanDefinition` 类的一些关键代码:

 

```java
public abstract class AbstractBeanDefinition implements BeanDefinition, Cloneable {
 
    @Nullable
    private volatile Object beanClass;
 
    @Nullable
    private String scope = SCOPE_DEFAULT;
 
    private boolean singleton = true;
    private boolean prototype = false;
 
    @Nullable
    private String initMethodName;
 
    @Nullable
    private String destroyMethodName;
 
    private ConstructorArgumentValues constructorArgumentValues;
 
    private MutablePropertyValues propertyValues;
 
    protected AbstractBeanDefinition() {
        this(null, null);
    }
 
    protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs,
                                     @Nullable MutablePropertyValues pvs) {
        this.constructorArgumentValues = (cargs != null ? cargs : new ConstructorArgumentValues());
        this.propertyValues = (pvs != null ? pvs : new MutablePropertyValues());
    }
 
    @Override
    @Nullable
    public String getBeanClassName() {
        Object beanClassObject = this.beanClass;
        return (beanClassObject instanceof Class ? ((Class<?>) beanClassObject).getName() : (String) beanClassObject);
    }
 
    @Override
    public void setBeanClassName(@Nullable String beanClassName) {
        this.beanClass = beanClassName;
    }
 
    @Override
    @Nullable
    public String getScope() {
        return this.scope;
    }
 
    @Override
    public void setScope(@Nullable String scope) {
        this.scope = scope;
        this.singleton = SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
        this.prototype = SCOPE_PROTOTYPE.equals(scope);
    }
 
    @Override
    public boolean isSingleton() {
        return this.singleton;
    }
 
    @Override
    public boolean isPrototype() {
        return this.prototype;
    }
 
    @Override
    @Nullable
    public String getInitMethodName() {
        return this.initMethodName;
    }
 
    @Override
    public void setInitMethodName(@Nullable String initMethodName) {
        this.initMethodName = initMethodName;
    }
 
    @Override
    @Nullable
    public String getDestroyMethodName() {
        return this.destroyMethodName;
    }
 
    @Override
    public void setDestroyMethodName(@Nullable String destroyMethodName) {
        this.destroyMethodName = destroyMethodName;
    }
 
    @Override
    public ConstructorArgumentValues getConstructorArgumentValues() {
        return this.constructorArgumentValues;
    }
 
    @Override
    public MutablePropertyValues getPropertyValues() {
        return this.propertyValues;
    }
 
    @Override
    public AbstractBeanDefinition cloneBeanDefinition() {
        try {
            return (AbstractBeanDefinition) super.clone();
        } catch (CloneNotSupportedException ex) {
            throw new IllegalStateException("Should never happen", ex);
        }
    }
}
```

 

5. 解析 BeanDefinition 的使用

 

`BeanDefinition` 通常通过 XML 配置文件、注解配置或编程方式进行注册。在 Spring 启动过程中,这些 `BeanDefinition` 会被解析并注册到 `BeanFactory` 中。

 

5.1 通过 XML 配置注册 BeanDefinition

 

在 XML 配置文件中定义 Bean 时,Spring 会使用 `XmlBeanDefinitionReader` 来解析 XML 文件并生成相应的 `BeanDefinition` 对象。

 

```xml
<bean id="exampleBean" class="com.example.MyClass" scope="singleton">
    <property name="name" value="example"/>
</bean>
```

 

5.2 通过注解配置注册 BeanDefinition

 

使用注解时,Spring 会通过 `ClassPathBeanDefinitionScanner` 扫描类路径下的注解并生成 `BeanDefinition`。

 

```java
@Component
public class ExampleBean {
    // ...
}
```

 

5.3 通过编程方式注册 BeanDefinition

 

可以通过编程方式手动创建和注册 `BeanDefinition`。

 

```java
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyClass.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
context.registerBeanDefinition("myBean", beanDefinition);
context.refresh();
```

 

6. 总结

 

通过深入了解 `BeanDefinition` 及其相关实现类,我们可以看到 Spring 是如何描述和管理 Bean 的元数据的。`BeanDefinition` 的设计使得 Spring 容器能够以统一的方式处理不同来源的 Bean 定义,不论是 XML 配置、注解还是编程方式。这种灵活性和统一性是 Spring 框架强大和广受欢迎的重要原因之一。通过分析这些源码,我们可以更好地理解 Spring 的工作原理,并在实际开发中更有效地使用和扩展 Spring 框架。

目录
相关文章
|
3天前
|
Java 对象存储 开发者
解析Spring Cloud与Netflix OSS:微服务架构中的左右手如何协同作战
Spring Cloud与Netflix OSS不仅是现代微服务架构中不可或缺的一部分,它们还通过不断的技术创新和社区贡献推动了整个行业的发展。无论是对于初创企业还是大型组织来说,掌握并合理运用这两套工具,都能极大地提升软件系统的灵活性、可扩展性以及整体性能。随着云计算和容器化技术的进一步普及,Spring Cloud与Netflix OSS将继续引领微服务技术的发展潮流。
12 0
|
13天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
13天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
13天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
88 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
13天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
156 37
|
3天前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
35 10
|
5天前
|
编解码 开发工具 UED
QT Widgets模块源码解析与实践
【9月更文挑战第20天】Qt Widgets 模块是 Qt 开发中至关重要的部分,提供了丰富的 GUI 组件,如按钮、文本框等,并支持布局管理、事件处理和窗口管理。这些组件基于信号与槽机制,实现灵活交互。通过对源码的解析及实践应用,可深入了解其类结构、布局管理和事件处理机制,掌握创建复杂 UI 界面的方法,提升开发效率和用户体验。
47 12
|
3天前
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
3天前
|
XML 存储 Java
Spring-源码深入分析(二)
Spring-源码深入分析(二)
|
3天前
|
XML 设计模式 Java
Spring-源码深入分析(一)
Spring-源码深入分析(一)

推荐镜像

更多