Spring 系列(一):用三条主线理解 Spring:BeanDefinition、生命周期与 AOP

用三条主线理解 Spring:BeanDefinition、生命周期与 AOP

如果只能用三条主线来理解 Spring 框架,那么一定是:

BeanDefinition 的加载、Bean 的生命周期、AOP 如何嵌入生命周期。

Spring 中绝大多数看起来"复杂"的机制,本质上都是这三点的组合与演化。


一、为什么要用"三条主线"来理解 Spring?

在学习 Spring 的过程中,很多人都会遇到类似困惑:

  • 注解越来越多,却不知道它们到底在什么时候生效
  • 自动装配看似神秘,不清楚真正的触发点
  • 事务、AOP、循环依赖的问题反复出现

根本原因并不是 Spring 太复杂,而是没有从结构性视角去理解它

Spring 并不是一个"以注解为中心"的框架,而是一个分阶段、强约束的 IoC 容器系统。从整体上看,它几乎所有能力都围绕三个阶段展开:

  1. 容器结构的构建阶段(BeanDefinition)
  2. 对象创建与管理阶段(Bean 生命周期)
  3. 方法行为增强阶段(AOP)

抓住这三条主线,绝大多数 Spring 行为都可以被反向推导出来。


二、第一条主线:BeanDefinition ------ 容器结构层

1. Spring 真正管理的不是 Bean,而是 BeanDefinition

在 Spring 容器启动的早期,并不会立刻创建任何业务对象。此时 Spring 关注的核心问题只有一个:

容器里应该有哪些 Bean,它们应该如何被创建?

这些信息不会以"对象"的形式存在,而是被统一抽象为:

text 复制代码
BeanDefinition

你可以把 BeanDefinition 理解为一张"造 Bean 的说明书",其中包含:

  • Bean 对应的 class
  • scope(singleton / prototype)
  • 是否懒加载
  • 依赖关系
  • 工厂方法
  • 初始化 / 销毁方法

在这个阶段,容器中只有定义,没有实例。


2. BeanDefinition 阶段能做什么?

这是 Spring 启动过程中唯一可以改变容器结构的阶段

在这一阶段,框架或用户代码可以:

  • 新增 BeanDefinition
  • 删除或替换已有 BeanDefinition
  • 决定 Bean 是否注册
  • 修改 scope、role、lazy 等元信息

一旦进入 Bean 生命周期阶段,容器会冻结配置,结构将不再允许被修改。


3. 为什么大量框架注解都工作在这一阶段?

因为只有在 BeanDefinition 阶段,注解才能真正影响"有没有这个 Bean"。

常见例子包括:

  • MyBatis 的 @Mapper
  • Dubbo 的 @EnableDubbo
  • Spring Boot 的自动装配

这些注解背后,通常都会借助:

  • ImportSelector
  • ImportBeanDefinitionRegistrar
  • BeanDefinitionRegistryPostProcessor

它们的目标只有一个:

把注解携带的元信息,转换成 BeanDefinition 并注册进容器。


三、第二条主线:Bean 生命周期 ------ 对象管理层

当所有 BeanDefinition 注册完成并被冻结之后,Spring 才真正进入"创建对象"的阶段。

1. 生命周期的本质是什么?

从本质上看,Bean 生命周期做的事情只有一件:

把一次简单的 new 操作,拆分成多个可插拔的阶段。

一个典型的单例 Bean,会经历如下步骤:

  1. 实例化(构造方法执行)
  2. 属性填充(依赖注入)
  3. Aware 接口回调
  4. 初始化前处理(BeanPostProcessor
  5. 初始化方法(@PostConstruct / afterPropertiesSet / init-method)
  6. 初始化后处理(BeanPostProcessor
  7. 放入单例池

这种拆分,为 Spring 的扩展能力奠定了基础。


2. 生命周期为什么要拆得这么细?

因为 Spring 需要在对象创建的不同时间点,允许"外部逻辑"介入,例如:

  • 依赖注入
  • 循环依赖处理
  • AOP 代理生成
  • 容器感知能力(Aware)

如果对象一开始就被完整创建,这些能力将无法实现。


3. 循环依赖为什么只能 setter 注入解决?

Spring 解决循环依赖的前提条件是:

对象已经被实例化出来,即使它还没有完成初始化。

Setter / Field 注入的流程是:

text 复制代码
实例化对象
  ↓
提前暴露对象引用
  ↓
依赖注入

而构造器注入在实例化阶段就需要完整依赖:

text 复制代码
构造器执行
  ↓
需要依赖对象

此时对象尚不存在,Spring 无法提前暴露引用,因此无法解决构造器循环依赖。


四、第三条主线:AOP ------ 行为增强层

AOP 并不是一个独立于 IoC 的系统,而是深度嵌入 Bean 生命周期中的一种扩展机制

1. AOP 真正发生在什么时候?

AOP 并不是在方法调用时"临时判断要不要增强",而是在 Bean 创建完成之后,就已经决定好要不要生成代理对象

也就是说:

AOP 发生在 Bean 创建期,行为生效在方法调用期。


2. AOP 是如何嵌入生命周期的?

Spring AOP 通过实现 BeanPostProcessor,在 初始化后阶段 对 Bean 进行处理。

以事务为例:

  • @Transactional 只是一个元数据注解
  • 真正起作用的是 TransactionInterceptor
  • 它会在 postProcessAfterInitialization 阶段判断是否需要创建代理

如果需要,Spring 会返回代理对象,并用它替换原始 Bean。


3. 为什么事务、自调用会失效?

java 复制代码
@Service
public class AService {
    @Transactional
    public void a() {
        this.b();
    }

    @Transactional
    public void b() {}
}

实际调用路径是:

text 复制代码
外部调用 → 代理对象.a()
            → 目标对象.a()
                → this.b()

this.b() 并没有经过代理,自然也不会进入事务拦截器,因此事务不会生效。


4. AOP 与 BeanDefinition 的边界

AOP 只能:

  • 包装 Bean
  • 拦截方法调用

但它不能

  • 决定 Bean 是否存在
  • 改变 Bean 的 scope
  • 修改依赖结构

这些能力,全部属于 BeanDefinition 阶段


五、用这三条主线反推 Spring 的一切行为

掌握这三条主线之后,很多问题都可以自然解释:

  • 注解不生效 → BeanDefinition 是否被注册
  • 循环依赖异常 → 是否构造器注入
  • 事务不生效 → 是否走了代理
  • Starter 无感接入 → BeanDefinition 阶段完成装配

六、一句话总结

Spring 的核心可以归纳为三件事:

第一,构建容器结构(BeanDefinition);
第二,按生命周期管理对象(Bean Lifecycle);
第三,在生命周期合适的阶段织入 AOP 行为增强。

当你从这个视角再回头看 Spring,会发现:

  • 它并不神秘
  • 也不全是"魔法"
  • 而是一个被工程需求不断扩展、但主干极其清晰的框架

理解这三条主线,你就已经站在了 Spring 框架设计者的视角

相关推荐
独自破碎E2 小时前
介绍一下Spring AI框架
java·人工智能·spring
sin22012 小时前
Spring事务管理(SpringBoot)
java·spring boot·spring
C***11502 小时前
Spring TransactionTemplate 深入解析与高级用法
java·数据库·spring
程序猿零零漆3 小时前
Spring之旅 - 记录学习 Spring 框架的过程和经验(十三)SpringMVC快速入门、请求处理
java·学习·spring
d***81723 小时前
springboot 修复 Spring Framework 特定条件下目录遍历漏洞(CVE-2024-38819)
spring boot·后端·spring
廋到被风吹走4 小时前
【Spring】 Spring Cloud 服务注册与发现深度解析:Eureka/Nacos/Consul 源码、AP vs CP 与自我保护机制
spring·spring cloud·java-consul
计算机学姐5 小时前
基于SpringBoot的汽车租赁系统【个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·spring·汽车·推荐算法
8***f3955 小时前
Spring 中使用Mybatis,超详细
spring·tomcat·mybatis
我是人✓5 小时前
Spring IOC入门
java·数据库·spring