0%

Spring Bean 生命周期深度解析:从初始化到销毁的完整流程

Spring Bean 的生命周期是 Spring 容器管理 Bean 的核心逻辑,涵盖 “Bean 定义加载→实例化→属性注入→初始化→使用→销毁” 全流程。每个阶段都允许开发者通过接口或注解插入自定义逻辑,而 后置处理器(BeanPostProcessor/BeanFactoryPostProcessor) 则是扩展生命周期的关键机制。从 “生命周期完整流程→核心阶段解析→后置处理器详解→实战验证” 四个维度,彻底拆解 Spring Bean 的生命周期。

Spring Bean 生命周期全景图(核心流程)

Spring Bean 的生命周期可分为 “容器初始化阶段”“容器销毁阶段”,每个阶段包含多个关键节点,严格遵循固定顺序:

graph TD
    A[容器初始化:加载BeanDefinition] --> B[调用BeanFactoryPostProcessor 修改BeanDefinition]
    B --> C[Bean实例化:调用构造器]
    C --> D[属性注入:调用setter方法]
    D --> E[Aware接口回调:BeanNameAware->BeanFactoryAware->ApplicationContextAware]
    E --> F[BeanPostProcessor前置处理:postProcessBeforeInitialization]
    F --> G["初始化回调:@PostConstruct->InitializingBean->init-method"]
    G --> H[BeanPostProcessor后置处理:postProcessAfterInitialization]
    H --> I[Bean就绪:容器初始化完成,可使用Bean]
    I --> J[容器销毁触发]
    J --> K["销毁回调:@PreDestroy->DisposableBean->destroy-method"]

容器初始化阶段:Bean 的创建与初始化

容器初始化阶段是 Bean 从 “定义” 到 “就绪” 的核心过程,每个节点都有明确的职责和触发时机。逐阶段解析:

1. 阶段 1:BeanFactoryPostProcessor 调用(容器级后置处理)

  • 触发时机:Spring 容器加载完所有 BeanDefinition(Bean 的元数据)后,Bean 实例化前(此时仅解析配置,未创建任何 Bean 实例)。
  • 核心作用:修改 BeanDefinition 的配置(如动态修改属性值、添加依赖),扩展容器功能。
  • 实现方式:实现 BeanFactoryPostProcessor 接口,重写 postProcessBeanFactory 方法。
代码对应与输出
1
2
3
4
5
6
7
8
// 容器后置处理器实现
@Component
class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor#postProcessBeanFactory");
}
}
阅读全文 »

SQL 关系分类与语言分类详解

SQL(结构化查询语言)是操作关系型数据库的标准语言,其体系可从关系类型语言功能两个维度进行分类。理解这些分类有助于清晰把握 SQL 的核心功能和应用场景。

SQL 关系分类(数据存储形式)

SQL 中涉及的 “关系” 本质上是二维表结构,根据存储方式和生命周期可分为三类:

1. 表(Table):物理存储的基础关系

  • 定义:数据库中永久存储的二维表,包含行(记录)和列(字段),是数据的物理载体。

  • 特性:

    • 独立存在于数据库中,数据持久化存储在磁盘上。
    • 支持 INSERTUPDATEDELETE 等操作修改数据。
    • 结构由 CREATE TABLE 定义,可通过 ALTER TABLE 修改。
  • 示例:

    1
    2
    3
    4
    5
    -- 创建表(物理存储)
    CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
    );

2. 视图(View):逻辑定义的虚拟关系

  • 定义:由 SELECT 查询定义的虚拟表,不实际存储数据,仅保存查询逻辑,使用时动态计算结果。

  • 特性:

    • 数据依赖于基础表(视图的数据源),基础表数据变化会实时反映到视图。
    • 可简化复杂查询(将多表关联逻辑封装为视图),并限制用户访问范围(如隐藏敏感字段)。
    • 支持 SELECT 操作,部分视图可通过 INSERT/UPDATE/DELETE 修改(需满足特定条件,如基于单表且包含主键)。
  • 示例:

阅读全文 »

Spring 依赖注入(DI)详解:从原理到实践

依赖注入(Dependency Injection,简称 DI)是 Spring 框架的核心特性之一,是控制反转(IoC)思想的具体实现。它通过容器自动管理对象之间的依赖关系,替代了传统代码中手动创建依赖对象的方式,大幅降低了代码耦合度。本文从 “DI 核心概念” 到 “两种注入方式实战”,系统解析 Spring DI 的工作原理与最佳实践。

DI 与 IoC:理解核心概念

1. 传统开发的痛点:主动依赖导致高耦合

在没有 DI 的时代,对象需要主动创建其依赖的对象,导致代码耦合严重,难以维护和测试:

1
2
3
4
5
6
7
8
9
10
public class Person {
// 主动创建依赖对象,耦合度高
private Car car = new Car();
private House house = new House();

// 业务逻辑依赖于具体的 Car 和 House 实现
public void goOut() {
car.drive(); // 直接依赖 Car 实例
}
}

问题:若 Car 构造器变化(如新增参数),Person 类必须修改;更换 Car 实现(如从 Benz 改为 BMW),需修改 Person 代码。

2. 控制反转(IoC):反转依赖的创建权

IoC 核心思想:将对象的创建和依赖管理交给容器,对象只需 “被动接收” 依赖,无需主动创建。

  • 传统方式:对象 → 主动创建依赖(正转控制);
  • IoC 方式:容器 → 主动注入依赖给对象(反转控制)。

Spring 中,IoC 容器(如 BeanFactoryApplicationContext)是实现者,负责:

  • 管理对象的生命周期(创建、初始化、销毁);
  • 解析对象之间的依赖关系;
  • 在对象需要时自动注入依赖。

3. 依赖注入(DI):IoC 的具体实现

DI 是 IoC 的一种具体表现形式:容器在实例化对象时,自动将其依赖的对象注入进来,对象无需关心依赖的来源和创建过程。

阅读全文 »

Spring Bean 的继承与依赖:复用配置与控制实例化顺序

在 Spring 中,Bean 的继承和依赖是两种重要的配置机制。继承用于复用配置(减少重复代码),依赖用于控制 Bean 的实例化顺序。详细解析这两种机制的实现方式、使用场景及注意事项。

Bean 的继承:复用配置,减少冗余

Spring 中的 Bean 继承并非 Java 中的类继承(不涉及类的父子关系),而是配置的继承:子 Bean 可以继承父 Bean 的所有配置(属性、依赖等),并可覆盖父 Bean 的配置。这类似于 “模板模式”,父 Bean 定义通用配置,子 Bean 仅需定义差异化部分。

1. 基本使用:通过 parent 属性实现继承

(1)普通 Bean 作为父 Bean

父 Bean 可以是一个可实例化的普通 Bean,子 Bean 通过 parent 属性指定父 Bean 的 id,从而继承其配置。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 父 Bean:定义通用配置 -->
<bean id="parentPerson" class="com.zhanghe.study.spring4.beans.beantest.Person">
<property name="name" value="张三"/> <!-- 通用属性:姓名 -->
<property name="car" ref="car"/> <!-- 通用依赖:Car 对象 -->
<property name="cars"> <!-- 通用集合:List<Car> -->
<list>
<ref bean="car"/>
<ref bean="car2"/>
</list>
</property>
</bean>

<!-- 子 Bean:继承父 Bean 并覆盖部分配置 -->
<bean id="sonPerson" parent="parentPerson">
<!-- 覆盖父 Bean 的 name 属性 -->
<property name="name" value="张飞"/>
<!-- 继承父 Bean 的 car、cars 配置,无需重复定义 -->
</bean>
阅读全文 »

Spring 配置 Bean 全指南:从 XML 到注解的完整实践

Spring 配置 Bean 的核心目标是将 Bean 的创建、依赖管理交给 IOC 容器,通过 XML 或注解定义 Bean 的元数据(如类名、依赖、生命周期),最终由容器统一实例化并装配。从 “XML 配置” 到 “注解配置”,系统拆解 Bean 的配置方式、依赖注入逻辑、自动装配规则及歧义性处理,同时对比两种配置方式的优缺点与最佳实践。

XML 配置 Bean:传统且灵活的配置方式

XML 是 Spring 早期最主流的 Bean 配置方式,支持复杂的 Bean 定义(如工厂 Bean、集合属性),适合需要明确配置流程的场景。其核心是通过 <bean> 标签定义 Bean,配合 <property>/<constructor-arg> 注入依赖。

1. 基础 Bean 配置:构造器与 Setter 注入

Spring 实例化 Bean 主要依赖构造器(默认无参构造器),依赖注入(DI)分为 Setter 注入(属性注入)和 构造器注入,分别对应不同的使用场景。

(1)Setter 注入(最常用)

核心原理:Spring 先通过无参构造器实例化 Bean,再调用属性的 setter 方法注入依赖。
关键要求:Bean 类必须提供无参构造器(若未显式定义任何构造器,JVM 会默认生成;若显式定义有参构造器,需手动添加无参构造器)。

1.1 简单类型注入(value 属性)

注入基本类型(String、int、double 等)或字符串,使用 value 属性:

1
2
3
4
5
6
<!-- 配置 HelloWorld Bean,Setter 注入 name 属性 -->
<bean id="helloWorld" class="com.zhanghe.study.spring4.beans.helloworld.HelloWorld">
<!-- name:对应 setName() 方法(去掉 set 后首字母小写,与成员变量名无关) -->
<!-- value:注入简单类型值 -->
<property name="name" value="Spring Hello"/>
</bean>

对应的 Java 类:

阅读全文 »