话说天下大事,合久必分,分久必合……废话少说,直接上干货 基于Spring Framework 6.x
深入分析 Spring IoC 容器从 AbstractApplicationContext.refresh() 到容器完全就绪的完整源码链路,覆盖 Bean 从定义到实例化的全生命周期。
目录
第一部分:理论基础
- 1.1 IoC 设计思想
- 1.2 依赖注入方式
- 1.3 IoC 容器的两种形态
- 1.4 容器继承层次
- 2.1 BeanDefinition — Bean 的元数据
- 2.2 Bean 的作用域 (Scope)
- 2.3 依赖注入详解
- 2.4 Bean 的命名与别名
- 2.5 FactoryBean vs BeanFactory
- 2.6 循环依赖问题
第二部分:源码分析
第一部分:理论基础
1. IoC 理论基础
1.1 什么是 IoC(控制反转)
1.1.1 传统编程方式的问题
在传统的编程方式中,对象自己负责获取它所依赖的对象:
// ❌ 传统方式:对象控制自己的依赖
public class UserService {
private UserRepository userRepository;
public UserService() {
// 对象自己创建依赖 —— 强耦合
this.userRepository = new JdbcUserRepository();
}
}
问题:
- 对象与具体实现类强耦合
- 难以替换依赖实现(如切换到 MyBatis 或 JPA)
- 难以进行单元测试(无法 Mock 依赖)
- 依赖的生命周期管理混乱
1.1.2 IoC 的思想
// ✅ IoC 方式:依赖由外部注入
public class UserService {
private UserRepository userRepository;
// 依赖由外部传入 —— 控制反转
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
#mermaid-svg-z42H2jixjOOkirEb{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-z42H2jixjOOkirEb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-z42H2jixjOOkirEb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-z42H2jixjOOkirEb .error-icon{fill:#552222;}#mermaid-svg-z42H2jixjOOkirEb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-z42H2jixjOOkirEb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-z42H2jixjOOkirEb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-z42H2jixjOOkirEb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-z42H2jixjOOkirEb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-z42H2jixjOOkirEb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-z42H2jixjOOkirEb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-z42H2jixjOOkirEb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-z42H2jixjOOkirEb .marker.cross{stroke:#333333;}#mermaid-svg-z42H2jixjOOkirEb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-z42H2jixjOOkirEb p{margin:0;}#mermaid-svg-z42H2jixjOOkirEb .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-z42H2jixjOOkirEb .cluster-label text{fill:#333;}#mermaid-svg-z42H2jixjOOkirEb .cluster-label span{color:#333;}#mermaid-svg-z42H2jixjOOkirEb .cluster-label span p{background-color:transparent;}#mermaid-svg-z42H2jixjOOkirEb .label text,#mermaid-svg-z42H2jixjOOkirEb span{fill:#333;color:#333;}#mermaid-svg-z42H2jixjOOkirEb .node rect,#mermaid-svg-z42H2jixjOOkirEb .node circle,#mermaid-svg-z42H2jixjOOkirEb .node ellipse,#mermaid-svg-z42H2jixjOOkirEb .node polygon,#mermaid-svg-z42H2jixjOOkirEb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-z42H2jixjOOkirEb .rough-node .label text,#mermaid-svg-z42H2jixjOOkirEb .node .label text,#mermaid-svg-z42H2jixjOOkirEb .image-shape .label,#mermaid-svg-z42H2jixjOOkirEb .icon-shape .label{text-anchor:middle;}#mermaid-svg-z42H2jixjOOkirEb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-z42H2jixjOOkirEb .rough-node .label,#mermaid-svg-z42H2jixjOOkirEb .node .label,#mermaid-svg-z42H2jixjOOkirEb .image-shape .label,#mermaid-svg-z42H2jixjOOkirEb .icon-shape .label{text-align:center;}#mermaid-svg-z42H2jixjOOkirEb .node.clickable{cursor:pointer;}#mermaid-svg-z42H2jixjOOkirEb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-z42H2jixjOOkirEb .arrowheadPath{fill:#333333;}#mermaid-svg-z42H2jixjOOkirEb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-z42H2jixjOOkirEb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-z42H2jixjOOkirEb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z42H2jixjOOkirEb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-z42H2jixjOOkirEb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z42H2jixjOOkirEb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-z42H2jixjOOkirEb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-z42H2jixjOOkirEb .cluster text{fill:#333;}#mermaid-svg-z42H2jixjOOkirEb .cluster span{color:#333;}#mermaid-svg-z42H2jixjOOkirEb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-z42H2jixjOOkirEb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-z42H2jixjOOkirEb rect.text{fill:none;stroke-width:0;}#mermaid-svg-z42H2jixjOOkirEb .icon-shape,#mermaid-svg-z42H2jixjOOkirEb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z42H2jixjOOkirEb .icon-shape p,#mermaid-svg-z42H2jixjOOkirEb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-z42H2jixjOOkirEb .icon-shape .label rect,#mermaid-svg-z42H2jixjOOkirEb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z42H2jixjOOkirEb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-z42H2jixjOOkirEb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-z42H2jixjOOkirEb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
控制反转
✅ IoC 方式
容器创建JdbcUserRepository
容器将依赖注入UserService
容器控制所有对象的生命周期
❌ 传统方式
UserService 自己创建new JdbcUserRepository()
UserService 控制依赖的创建和管理
IoC 的核心思想:
| 谁创建依赖? | 对象自己 | IoC 容器 |
| 谁管理生命周期? | 对象自己 | IoC 容器 |
| 控制权在哪? | 对象手中 | 容器手中(反转) |
| 耦合程度 | 强耦合 | 松耦合 |
| 可测试性 | 差 | 好(可注入 Mock) |
1.2 依赖注入(DI)—— IoC 的实现方式
依赖注入(Dependency Injection, DI)是 IoC 最主流的实现方式。Spring 支持三种注入方式:
#mermaid-svg-dyJnSg9ALuKitfw9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dyJnSg9ALuKitfw9 .error-icon{fill:#552222;}#mermaid-svg-dyJnSg9ALuKitfw9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dyJnSg9ALuKitfw9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dyJnSg9ALuKitfw9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dyJnSg9ALuKitfw9 .marker.cross{stroke:#333333;}#mermaid-svg-dyJnSg9ALuKitfw9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dyJnSg9ALuKitfw9 p{margin:0;}#mermaid-svg-dyJnSg9ALuKitfw9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster-label text{fill:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster-label span{color:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster-label span p{background-color:transparent;}#mermaid-svg-dyJnSg9ALuKitfw9 .label text,#mermaid-svg-dyJnSg9ALuKitfw9 span{fill:#333;color:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 .node rect,#mermaid-svg-dyJnSg9ALuKitfw9 .node circle,#mermaid-svg-dyJnSg9ALuKitfw9 .node ellipse,#mermaid-svg-dyJnSg9ALuKitfw9 .node polygon,#mermaid-svg-dyJnSg9ALuKitfw9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dyJnSg9ALuKitfw9 .rough-node .label text,#mermaid-svg-dyJnSg9ALuKitfw9 .node .label text,#mermaid-svg-dyJnSg9ALuKitfw9 .image-shape .label,#mermaid-svg-dyJnSg9ALuKitfw9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-dyJnSg9ALuKitfw9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dyJnSg9ALuKitfw9 .rough-node .label,#mermaid-svg-dyJnSg9ALuKitfw9 .node .label,#mermaid-svg-dyJnSg9ALuKitfw9 .image-shape .label,#mermaid-svg-dyJnSg9ALuKitfw9 .icon-shape .label{text-align:center;}#mermaid-svg-dyJnSg9ALuKitfw9 .node.clickable{cursor:pointer;}#mermaid-svg-dyJnSg9ALuKitfw9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dyJnSg9ALuKitfw9 .arrowheadPath{fill:#333333;}#mermaid-svg-dyJnSg9ALuKitfw9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dyJnSg9ALuKitfw9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dyJnSg9ALuKitfw9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dyJnSg9ALuKitfw9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dyJnSg9ALuKitfw9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dyJnSg9ALuKitfw9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster text{fill:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 .cluster span{color:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dyJnSg9ALuKitfw9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dyJnSg9ALuKitfw9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-dyJnSg9ALuKitfw9 .icon-shape,#mermaid-svg-dyJnSg9ALuKitfw9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dyJnSg9ALuKitfw9 .icon-shape p,#mermaid-svg-dyJnSg9ALuKitfw9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dyJnSg9ALuKitfw9 .icon-shape .label rect,#mermaid-svg-dyJnSg9ALuKitfw9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dyJnSg9ALuKitfw9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dyJnSg9ALuKitfw9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dyJnSg9ALuKitfw9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
依赖注入 (DI)
① 构造器注入通过构造器参数传入依赖★ 推荐方式- 不可变依赖- 保证依赖不为 null- 支持 final 字段
② Setter 注入通过 setter 方法传入依赖- 可选依赖- 可变依赖- 可重新配置
③ 字段注入通过 @Autowired 直接注入字段- 代码简洁- ✗ 不可变- ✗ 难以测试- ✗ 隐藏依赖
// ① 构造器注入 — 推荐
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// ② Setter 注入 — 可选依赖
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// ③ 字段注入 — 最简单但不推荐(但是工作过程中这种用法最多,至少我身边的人是这样的)
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}
1.3 IoC 容器的两种形态
1.3.1 BeanFactory — 基础容器
#mermaid-svg-N8aqMN8dKdPxdwch{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-N8aqMN8dKdPxdwch .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-N8aqMN8dKdPxdwch .error-icon{fill:#552222;}#mermaid-svg-N8aqMN8dKdPxdwch .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-N8aqMN8dKdPxdwch .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-N8aqMN8dKdPxdwch .marker{fill:#333333;stroke:#333333;}#mermaid-svg-N8aqMN8dKdPxdwch .marker.cross{stroke:#333333;}#mermaid-svg-N8aqMN8dKdPxdwch svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-N8aqMN8dKdPxdwch p{margin:0;}#mermaid-svg-N8aqMN8dKdPxdwch .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-N8aqMN8dKdPxdwch .cluster-label text{fill:#333;}#mermaid-svg-N8aqMN8dKdPxdwch .cluster-label span{color:#333;}#mermaid-svg-N8aqMN8dKdPxdwch .cluster-label span p{background-color:transparent;}#mermaid-svg-N8aqMN8dKdPxdwch .label text,#mermaid-svg-N8aqMN8dKdPxdwch span{fill:#333;color:#333;}#mermaid-svg-N8aqMN8dKdPxdwch .node rect,#mermaid-svg-N8aqMN8dKdPxdwch .node circle,#mermaid-svg-N8aqMN8dKdPxdwch .node ellipse,#mermaid-svg-N8aqMN8dKdPxdwch .node polygon,#mermaid-svg-N8aqMN8dKdPxdwch .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-N8aqMN8dKdPxdwch .rough-node .label text,#mermaid-svg-N8aqMN8dKdPxdwch .node .label text,#mermaid-svg-N8aqMN8dKdPxdwch .image-shape .label,#mermaid-svg-N8aqMN8dKdPxdwch .icon-shape .label{text-anchor:middle;}#mermaid-svg-N8aqMN8dKdPxdwch .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-N8aqMN8dKdPxdwch .rough-node .label,#mermaid-svg-N8aqMN8dKdPxdwch .node .label,#mermaid-svg-N8aqMN8dKdPxdwch .image-shape .label,#mermaid-svg-N8aqMN8dKdPxdwch .icon-shape .label{text-align:center;}#mermaid-svg-N8aqMN8dKdPxdwch .node.clickable{cursor:pointer;}#mermaid-svg-N8aqMN8dKdPxdwch .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-N8aqMN8dKdPxdwch .arrowheadPath{fill:#333333;}#mermaid-svg-N8aqMN8dKdPxdwch .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-N8aqMN8dKdPxdwch .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-N8aqMN8dKdPxdwch .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-N8aqMN8dKdPxdwch .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-N8aqMN8dKdPxdwch .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-N8aqMN8dKdPxdwch .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-N8aqMN8dKdPxdwch .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-N8aqMN8dKdPxdwch .cluster text{fill:#333;}#mermaid-svg-N8aqMN8dKdPxdwch .cluster span{color:#333;}#mermaid-svg-N8aqMN8dKdPxdwch div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-N8aqMN8dKdPxdwch .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-N8aqMN8dKdPxdwch rect.text{fill:none;stroke-width:0;}#mermaid-svg-N8aqMN8dKdPxdwch .icon-shape,#mermaid-svg-N8aqMN8dKdPxdwch .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-N8aqMN8dKdPxdwch .icon-shape p,#mermaid-svg-N8aqMN8dKdPxdwch .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-N8aqMN8dKdPxdwch .icon-shape .label rect,#mermaid-svg-N8aqMN8dKdPxdwch .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-N8aqMN8dKdPxdwch .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-N8aqMN8dKdPxdwch .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-N8aqMN8dKdPxdwch :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
BeanFactory 接口(基础 IoC 容器)
核心功能:
getBean() — 获取 Bean
containsBean() — 判断是否存在
isSingleton() / isPrototype() — 判断作用域
getType() — 获取 Bean 类型
getAliases() — 获取别名
设计原则:
★ 延迟加载 (Lazy Loading)首次 getBean() 时才实例化
最小内存占用
适用于资源受限环境
1.3.2 ApplicationContext — 高级容器
#mermaid-svg-mJDfbhzCWSDZstdx{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mJDfbhzCWSDZstdx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mJDfbhzCWSDZstdx .error-icon{fill:#552222;}#mermaid-svg-mJDfbhzCWSDZstdx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mJDfbhzCWSDZstdx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mJDfbhzCWSDZstdx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mJDfbhzCWSDZstdx .marker.cross{stroke:#333333;}#mermaid-svg-mJDfbhzCWSDZstdx svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mJDfbhzCWSDZstdx p{margin:0;}#mermaid-svg-mJDfbhzCWSDZstdx .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-mJDfbhzCWSDZstdx .cluster-label text{fill:#333;}#mermaid-svg-mJDfbhzCWSDZstdx .cluster-label span{color:#333;}#mermaid-svg-mJDfbhzCWSDZstdx .cluster-label span p{background-color:transparent;}#mermaid-svg-mJDfbhzCWSDZstdx .label text,#mermaid-svg-mJDfbhzCWSDZstdx span{fill:#333;color:#333;}#mermaid-svg-mJDfbhzCWSDZstdx .node rect,#mermaid-svg-mJDfbhzCWSDZstdx .node circle,#mermaid-svg-mJDfbhzCWSDZstdx .node ellipse,#mermaid-svg-mJDfbhzCWSDZstdx .node polygon,#mermaid-svg-mJDfbhzCWSDZstdx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mJDfbhzCWSDZstdx .rough-node .label text,#mermaid-svg-mJDfbhzCWSDZstdx .node .label text,#mermaid-svg-mJDfbhzCWSDZstdx .image-shape .label,#mermaid-svg-mJDfbhzCWSDZstdx .icon-shape .label{text-anchor:middle;}#mermaid-svg-mJDfbhzCWSDZstdx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mJDfbhzCWSDZstdx .rough-node .label,#mermaid-svg-mJDfbhzCWSDZstdx .node .label,#mermaid-svg-mJDfbhzCWSDZstdx .image-shape .label,#mermaid-svg-mJDfbhzCWSDZstdx .icon-shape .label{text-align:center;}#mermaid-svg-mJDfbhzCWSDZstdx .node.clickable{cursor:pointer;}#mermaid-svg-mJDfbhzCWSDZstdx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mJDfbhzCWSDZstdx .arrowheadPath{fill:#333333;}#mermaid-svg-mJDfbhzCWSDZstdx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mJDfbhzCWSDZstdx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mJDfbhzCWSDZstdx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJDfbhzCWSDZstdx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mJDfbhzCWSDZstdx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJDfbhzCWSDZstdx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mJDfbhzCWSDZstdx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mJDfbhzCWSDZstdx .cluster text{fill:#333;}#mermaid-svg-mJDfbhzCWSDZstdx .cluster span{color:#333;}#mermaid-svg-mJDfbhzCWSDZstdx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mJDfbhzCWSDZstdx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mJDfbhzCWSDZstdx rect.text{fill:none;stroke-width:0;}#mermaid-svg-mJDfbhzCWSDZstdx .icon-shape,#mermaid-svg-mJDfbhzCWSDZstdx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJDfbhzCWSDZstdx .icon-shape p,#mermaid-svg-mJDfbhzCWSDZstdx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mJDfbhzCWSDZstdx .icon-shape .label rect,#mermaid-svg-mJDfbhzCWSDZstdx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJDfbhzCWSDZstdx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mJDfbhzCWSDZstdx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mJDfbhzCWSDZstdx :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ApplicationContext 接口(高级 IoC 容器,继承 BeanFactory)
额外能力:
📢 事件发布 (ApplicationEvent)
🌍 国际化 (MessageSource)
📄 资源加载 (ResourceLoader)
🌱 环境抽象 (Environment + Profile)
🔧 自动装配 (BeanFactoryPostProcessor)
设计原则:
★ 预加载 (Eager Loading)启动时实例化所有单例 Bean
启动时完成所有初始化工作
运行时直接使用,无延迟
1.3.3 对比总结
#mermaid-svg-45wPRIfVPx4xVHYV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-45wPRIfVPx4xVHYV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-45wPRIfVPx4xVHYV .error-icon{fill:#552222;}#mermaid-svg-45wPRIfVPx4xVHYV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-45wPRIfVPx4xVHYV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-45wPRIfVPx4xVHYV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-45wPRIfVPx4xVHYV .marker.cross{stroke:#333333;}#mermaid-svg-45wPRIfVPx4xVHYV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-45wPRIfVPx4xVHYV p{margin:0;}#mermaid-svg-45wPRIfVPx4xVHYV g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-45wPRIfVPx4xVHYV g.classGroup text .title{font-weight:bolder;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster-label text{fill:#333;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster-label span{color:#333;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster-label span p{background-color:transparent;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster text{fill:#333;}#mermaid-svg-45wPRIfVPx4xVHYV .cluster span{color:#333;}#mermaid-svg-45wPRIfVPx4xVHYV .nodeLabel,#mermaid-svg-45wPRIfVPx4xVHYV .edgeLabel{color:#131300;}#mermaid-svg-45wPRIfVPx4xVHYV .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-45wPRIfVPx4xVHYV .label text{fill:#131300;}#mermaid-svg-45wPRIfVPx4xVHYV .labelBkg{background:#ECECFF;}#mermaid-svg-45wPRIfVPx4xVHYV .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-45wPRIfVPx4xVHYV .classTitle{font-weight:bolder;}#mermaid-svg-45wPRIfVPx4xVHYV .node rect,#mermaid-svg-45wPRIfVPx4xVHYV .node circle,#mermaid-svg-45wPRIfVPx4xVHYV .node ellipse,#mermaid-svg-45wPRIfVPx4xVHYV .node polygon,#mermaid-svg-45wPRIfVPx4xVHYV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-45wPRIfVPx4xVHYV .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV g.clickable{cursor:pointer;}#mermaid-svg-45wPRIfVPx4xVHYV g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-45wPRIfVPx4xVHYV g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-45wPRIfVPx4xVHYV .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-45wPRIfVPx4xVHYV .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-45wPRIfVPx4xVHYV .dashed-line{stroke-dasharray:3;}#mermaid-svg-45wPRIfVPx4xVHYV .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-45wPRIfVPx4xVHYV #compositionStart,#mermaid-svg-45wPRIfVPx4xVHYV .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #compositionEnd,#mermaid-svg-45wPRIfVPx4xVHYV .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #dependencyStart,#mermaid-svg-45wPRIfVPx4xVHYV .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #dependencyStart,#mermaid-svg-45wPRIfVPx4xVHYV .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #extensionStart,#mermaid-svg-45wPRIfVPx4xVHYV .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #extensionEnd,#mermaid-svg-45wPRIfVPx4xVHYV .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #aggregationStart,#mermaid-svg-45wPRIfVPx4xVHYV .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #aggregationEnd,#mermaid-svg-45wPRIfVPx4xVHYV .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #lollipopStart,#mermaid-svg-45wPRIfVPx4xVHYV .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV #lollipopEnd,#mermaid-svg-45wPRIfVPx4xVHYV .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-45wPRIfVPx4xVHYV .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-45wPRIfVPx4xVHYV .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-45wPRIfVPx4xVHYV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-45wPRIfVPx4xVHYV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-45wPRIfVPx4xVHYV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
«interface»
BeanFactory
+getBean(String name) : Object
+getBean(Class<T> type) : T
+containsBean(String name) : boolean
+isSingleton(String name) : boolean
+getType(String name) : Class<?>
«interface»
ApplicationContext
+getEnvironment() : ConfigurableEnvironment
+publishEvent(ApplicationEvent event)
+getApplicationName() : String
+getStartupDate() : long
基础 IoC 容器\\n提供 Bean 的获取和查询
高级容器\\n继承 BeanFactory\\n增加事件、国际化、环境等
| 定位 | 底层 IoC 容器接口 | 高级容器接口,继承 BeanFactory |
| Bean 实例化 | 延迟加载(首次 getBean 时才实例化) | 预加载(启动时实例化所有单例 Bean) |
| 国际化 | 不支持 | 支持 MessageSource |
| 事件机制 | 不支持 | 支持 ApplicationEvent 发布/监听 |
| 资源加载 | 不支持 | 支持 ResourceLoader |
| 使用场景 | 资源受限环境(如 Applet) | 企业级应用(绝大多数场景) |
1.4 容器继承层次体系
Spring 容器支持父子容器的层次结构:
#mermaid-svg-CKMNQwjilqqaaL5G{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CKMNQwjilqqaaL5G .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CKMNQwjilqqaaL5G .error-icon{fill:#552222;}#mermaid-svg-CKMNQwjilqqaaL5G .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CKMNQwjilqqaaL5G .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CKMNQwjilqqaaL5G .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CKMNQwjilqqaaL5G .marker.cross{stroke:#333333;}#mermaid-svg-CKMNQwjilqqaaL5G svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CKMNQwjilqqaaL5G p{margin:0;}#mermaid-svg-CKMNQwjilqqaaL5G .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CKMNQwjilqqaaL5G .cluster-label text{fill:#333;}#mermaid-svg-CKMNQwjilqqaaL5G .cluster-label span{color:#333;}#mermaid-svg-CKMNQwjilqqaaL5G .cluster-label span p{background-color:transparent;}#mermaid-svg-CKMNQwjilqqaaL5G .label text,#mermaid-svg-CKMNQwjilqqaaL5G span{fill:#333;color:#333;}#mermaid-svg-CKMNQwjilqqaaL5G .node rect,#mermaid-svg-CKMNQwjilqqaaL5G .node circle,#mermaid-svg-CKMNQwjilqqaaL5G .node ellipse,#mermaid-svg-CKMNQwjilqqaaL5G .node polygon,#mermaid-svg-CKMNQwjilqqaaL5G .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CKMNQwjilqqaaL5G .rough-node .label text,#mermaid-svg-CKMNQwjilqqaaL5G .node .label text,#mermaid-svg-CKMNQwjilqqaaL5G .image-shape .label,#mermaid-svg-CKMNQwjilqqaaL5G .icon-shape .label{text-anchor:middle;}#mermaid-svg-CKMNQwjilqqaaL5G .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CKMNQwjilqqaaL5G .rough-node .label,#mermaid-svg-CKMNQwjilqqaaL5G .node .label,#mermaid-svg-CKMNQwjilqqaaL5G .image-shape .label,#mermaid-svg-CKMNQwjilqqaaL5G .icon-shape .label{text-align:center;}#mermaid-svg-CKMNQwjilqqaaL5G .node.clickable{cursor:pointer;}#mermaid-svg-CKMNQwjilqqaaL5G .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CKMNQwjilqqaaL5G .arrowheadPath{fill:#333333;}#mermaid-svg-CKMNQwjilqqaaL5G .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CKMNQwjilqqaaL5G .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CKMNQwjilqqaaL5G .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CKMNQwjilqqaaL5G .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CKMNQwjilqqaaL5G .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CKMNQwjilqqaaL5G .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CKMNQwjilqqaaL5G .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CKMNQwjilqqaaL5G .cluster text{fill:#333;}#mermaid-svg-CKMNQwjilqqaaL5G .cluster span{color:#333;}#mermaid-svg-CKMNQwjilqqaaL5G div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CKMNQwjilqqaaL5G .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CKMNQwjilqqaaL5G rect.text{fill:none;stroke-width:0;}#mermaid-svg-CKMNQwjilqqaaL5G .icon-shape,#mermaid-svg-CKMNQwjilqqaaL5G .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CKMNQwjilqqaaL5G .icon-shape p,#mermaid-svg-CKMNQwjilqqaaL5G .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CKMNQwjilqqaaL5G .icon-shape .label rect,#mermaid-svg-CKMNQwjilqqaaL5G .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CKMNQwjilqqaaL5G .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CKMNQwjilqqaaL5G .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CKMNQwjilqqaaL5G :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
子容器可访问父容器的 Bean
是
否
是
否
父容器 (Root ApplicationContext)- 通常包含 Service、Repository- 业务逻辑层 Bean- 数据源、事务管理等基础设施
子容器 (Child ApplicationContext)- 通常包含 Controller- Web 层 Bean- 视图解析器等
子容器解析依赖时:
1. 先在子容器中查找
找到 ?
使用子容器的 Bean
2. 向父容器查找(委托)
父容器中找到 ?
使用父容器的 Bean
尝试创建 (仅子容器)
父容器解析依赖时:
★ 只在父容器中查找不能访问子容器的 Bean
典型场景:Spring MVC 中,DispatcherServlet 创建自己的子容器(WebApplicationContext),父容器是 ContextLoaderListener 创建的 Root ApplicationContext。Controller 在子容器中,Service/Repository 在父容器中。
2. Bean 核心知识
2.1 BeanDefinition — Bean 的元数据
2.1.1 什么是 BeanDefinition
BeanDefinition 是 Spring 中描述 Bean 的核心数据结构,它包含了创建 Bean 所需的全部元信息:
#mermaid-svg-ypiQs3bK5Mdaz5K3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .error-icon{fill:#552222;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .marker.cross{stroke:#333333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 p{margin:0;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster-label text{fill:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster-label span{color:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster-label span p{background-color:transparent;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .label text,#mermaid-svg-ypiQs3bK5Mdaz5K3 span{fill:#333;color:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .node rect,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node circle,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node ellipse,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node polygon,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .rough-node .label text,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node .label text,#mermaid-svg-ypiQs3bK5Mdaz5K3 .image-shape .label,#mermaid-svg-ypiQs3bK5Mdaz5K3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .rough-node .label,#mermaid-svg-ypiQs3bK5Mdaz5K3 .node .label,#mermaid-svg-ypiQs3bK5Mdaz5K3 .image-shape .label,#mermaid-svg-ypiQs3bK5Mdaz5K3 .icon-shape .label{text-align:center;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .node.clickable{cursor:pointer;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .arrowheadPath{fill:#333333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ypiQs3bK5Mdaz5K3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ypiQs3bK5Mdaz5K3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster text{fill:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .cluster span{color:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ypiQs3bK5Mdaz5K3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .icon-shape,#mermaid-svg-ypiQs3bK5Mdaz5K3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .icon-shape p,#mermaid-svg-ypiQs3bK5Mdaz5K3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .icon-shape .label rect,#mermaid-svg-ypiQs3bK5Mdaz5K3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ypiQs3bK5Mdaz5K3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ypiQs3bK5Mdaz5K3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ypiQs3bK5Mdaz5K3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
BeanDefinition(Bean 的 '配方')
核心属性:
beanClassName — 全限定类名
scope — 作用域 (singleton/prototype/…)
lazyInit — 是否懒加载
dependsOn — 依赖的其他 Bean
constructorArgumentValues — 构造器参数
propertyValues — 属性值
initMethodName — 初始化方法名
destroyMethodName — 销毁方法名
factoryMethodName — 工厂方法名
factoryBeanName — 工厂 Bean 名
isPrimary — 是否为首选 Bean
isAbstract — 是否为抽象定义(模板)
来源:
XML:
注解: @Component/@Service/@Repository/@Controller
Java Config: @Bean 方法
动态注册: BeanDefinitionRegistry.registerBeanDefinition()
2.1.2 BeanDefinition 的层次结构
#mermaid-svg-rOR3r36jzzpHS5nA{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rOR3r36jzzpHS5nA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rOR3r36jzzpHS5nA .error-icon{fill:#552222;}#mermaid-svg-rOR3r36jzzpHS5nA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rOR3r36jzzpHS5nA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rOR3r36jzzpHS5nA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rOR3r36jzzpHS5nA .marker.cross{stroke:#333333;}#mermaid-svg-rOR3r36jzzpHS5nA svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rOR3r36jzzpHS5nA p{margin:0;}#mermaid-svg-rOR3r36jzzpHS5nA g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-rOR3r36jzzpHS5nA g.classGroup text .title{font-weight:bolder;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster-label text{fill:#333;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster-label span{color:#333;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster-label span p{background-color:transparent;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster text{fill:#333;}#mermaid-svg-rOR3r36jzzpHS5nA .cluster span{color:#333;}#mermaid-svg-rOR3r36jzzpHS5nA .nodeLabel,#mermaid-svg-rOR3r36jzzpHS5nA .edgeLabel{color:#131300;}#mermaid-svg-rOR3r36jzzpHS5nA .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-rOR3r36jzzpHS5nA .label text{fill:#131300;}#mermaid-svg-rOR3r36jzzpHS5nA .labelBkg{background:#ECECFF;}#mermaid-svg-rOR3r36jzzpHS5nA .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-rOR3r36jzzpHS5nA .classTitle{font-weight:bolder;}#mermaid-svg-rOR3r36jzzpHS5nA .node rect,#mermaid-svg-rOR3r36jzzpHS5nA .node circle,#mermaid-svg-rOR3r36jzzpHS5nA .node ellipse,#mermaid-svg-rOR3r36jzzpHS5nA .node polygon,#mermaid-svg-rOR3r36jzzpHS5nA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rOR3r36jzzpHS5nA .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA g.clickable{cursor:pointer;}#mermaid-svg-rOR3r36jzzpHS5nA g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-rOR3r36jzzpHS5nA g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-rOR3r36jzzpHS5nA .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-rOR3r36jzzpHS5nA .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-rOR3r36jzzpHS5nA .dashed-line{stroke-dasharray:3;}#mermaid-svg-rOR3r36jzzpHS5nA .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-rOR3r36jzzpHS5nA #compositionStart,#mermaid-svg-rOR3r36jzzpHS5nA .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #compositionEnd,#mermaid-svg-rOR3r36jzzpHS5nA .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #dependencyStart,#mermaid-svg-rOR3r36jzzpHS5nA .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #dependencyStart,#mermaid-svg-rOR3r36jzzpHS5nA .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #extensionStart,#mermaid-svg-rOR3r36jzzpHS5nA .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #extensionEnd,#mermaid-svg-rOR3r36jzzpHS5nA .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #aggregationStart,#mermaid-svg-rOR3r36jzzpHS5nA .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #aggregationEnd,#mermaid-svg-rOR3r36jzzpHS5nA .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #lollipopStart,#mermaid-svg-rOR3r36jzzpHS5nA .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA #lollipopEnd,#mermaid-svg-rOR3r36jzzpHS5nA .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-rOR3r36jzzpHS5nA .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-rOR3r36jzzpHS5nA .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rOR3r36jzzpHS5nA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rOR3r36jzzpHS5nA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rOR3r36jzzpHS5nA :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
«interface»
BeanDefinition
+getBeanClassName()
+getScope()
+isSingleton()
+isPrototype()
+isLazyInit()
+getDependsOn()
+getPropertyValues()
+getConstructorArgumentValues()
+isPrimary()
AbstractBeanDefinition
#beanClass
#scope
#lazyInit
#dependsOn
#propertyValues
#constructorArgumentValues
-autowireMode
-initMethodName
-destroyMethodName
+overrideFrom(BeanDefinition)
GenericBeanDefinition
+setParentName()
+getParentName()
RootBeanDefinition
★ 合并后的最终定义
– 不再有父定义
– 不可变
– 运行时使用
«interface»
AnnotatedBeanDefinition
+getMetadata() : AnnotationMetadata
+getFactoryMethodMetadata()
★ 运行时使用的 Bean 定义\\n在 getMergedLocalBeanDefinition() 时生成\\n合并了父 BeanDefinition 的属性
2.1.3 BeanDefinition 的合并过程
#mermaid-svg-PmjWh2Nlp8uvyS9W{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PmjWh2Nlp8uvyS9W .error-icon{fill:#552222;}#mermaid-svg-PmjWh2Nlp8uvyS9W .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PmjWh2Nlp8uvyS9W .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .marker.cross{stroke:#333333;}#mermaid-svg-PmjWh2Nlp8uvyS9W svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PmjWh2Nlp8uvyS9W p{margin:0;}#mermaid-svg-PmjWh2Nlp8uvyS9W .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster-label text{fill:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster-label span{color:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster-label span p{background-color:transparent;}#mermaid-svg-PmjWh2Nlp8uvyS9W .label text,#mermaid-svg-PmjWh2Nlp8uvyS9W span{fill:#333;color:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .node rect,#mermaid-svg-PmjWh2Nlp8uvyS9W .node circle,#mermaid-svg-PmjWh2Nlp8uvyS9W .node ellipse,#mermaid-svg-PmjWh2Nlp8uvyS9W .node polygon,#mermaid-svg-PmjWh2Nlp8uvyS9W .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .rough-node .label text,#mermaid-svg-PmjWh2Nlp8uvyS9W .node .label text,#mermaid-svg-PmjWh2Nlp8uvyS9W .image-shape .label,#mermaid-svg-PmjWh2Nlp8uvyS9W .icon-shape .label{text-anchor:middle;}#mermaid-svg-PmjWh2Nlp8uvyS9W .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .rough-node .label,#mermaid-svg-PmjWh2Nlp8uvyS9W .node .label,#mermaid-svg-PmjWh2Nlp8uvyS9W .image-shape .label,#mermaid-svg-PmjWh2Nlp8uvyS9W .icon-shape .label{text-align:center;}#mermaid-svg-PmjWh2Nlp8uvyS9W .node.clickable{cursor:pointer;}#mermaid-svg-PmjWh2Nlp8uvyS9W .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .arrowheadPath{fill:#333333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PmjWh2Nlp8uvyS9W .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PmjWh2Nlp8uvyS9W .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PmjWh2Nlp8uvyS9W .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster text{fill:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W .cluster span{color:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PmjWh2Nlp8uvyS9W .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PmjWh2Nlp8uvyS9W rect.text{fill:none;stroke-width:0;}#mermaid-svg-PmjWh2Nlp8uvyS9W .icon-shape,#mermaid-svg-PmjWh2Nlp8uvyS9W .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PmjWh2Nlp8uvyS9W .icon-shape p,#mermaid-svg-PmjWh2Nlp8uvyS9W .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PmjWh2Nlp8uvyS9W .icon-shape .label rect,#mermaid-svg-PmjWh2Nlp8uvyS9W .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PmjWh2Nlp8uvyS9W .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PmjWh2Nlp8uvyS9W .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PmjWh2Nlp8uvyS9W :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
否
是
getMergedLocalBeanDefinition(beanName)
当前 BeanDefinition有 parentName ?
直接使用原始 GenericBeanDefinition转换为 RootBeanDefinition
获取父 BeanDefinition
★ 合并:- 子属性覆盖父属性- 子未定义的属性继承父- 生成 RootBeanDefinition
子 Bean 可覆盖:- beanClassName- scope- lazyInit- propertyValues- constructorArgumentValues
缓存为 mergedBeanDefinitions
返回 RootBeanDefinition(运行时使用的唯一 BeanDefinition 类型)
为什么需要合并? 通过父子 BeanDefinition,可以实现配置模板的复用 —— 父定义作为模板,多个子定义继承通用配置、覆盖特定配置。
2.2 Bean 的作用域 (Scope)
#mermaid-svg-mLNDD6fBVPxDXhuL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mLNDD6fBVPxDXhuL .error-icon{fill:#552222;}#mermaid-svg-mLNDD6fBVPxDXhuL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mLNDD6fBVPxDXhuL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mLNDD6fBVPxDXhuL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mLNDD6fBVPxDXhuL .marker.cross{stroke:#333333;}#mermaid-svg-mLNDD6fBVPxDXhuL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mLNDD6fBVPxDXhuL p{margin:0;}#mermaid-svg-mLNDD6fBVPxDXhuL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster-label text{fill:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster-label span{color:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster-label span p{background-color:transparent;}#mermaid-svg-mLNDD6fBVPxDXhuL .label text,#mermaid-svg-mLNDD6fBVPxDXhuL span{fill:#333;color:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL .node rect,#mermaid-svg-mLNDD6fBVPxDXhuL .node circle,#mermaid-svg-mLNDD6fBVPxDXhuL .node ellipse,#mermaid-svg-mLNDD6fBVPxDXhuL .node polygon,#mermaid-svg-mLNDD6fBVPxDXhuL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mLNDD6fBVPxDXhuL .rough-node .label text,#mermaid-svg-mLNDD6fBVPxDXhuL .node .label text,#mermaid-svg-mLNDD6fBVPxDXhuL .image-shape .label,#mermaid-svg-mLNDD6fBVPxDXhuL .icon-shape .label{text-anchor:middle;}#mermaid-svg-mLNDD6fBVPxDXhuL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mLNDD6fBVPxDXhuL .rough-node .label,#mermaid-svg-mLNDD6fBVPxDXhuL .node .label,#mermaid-svg-mLNDD6fBVPxDXhuL .image-shape .label,#mermaid-svg-mLNDD6fBVPxDXhuL .icon-shape .label{text-align:center;}#mermaid-svg-mLNDD6fBVPxDXhuL .node.clickable{cursor:pointer;}#mermaid-svg-mLNDD6fBVPxDXhuL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mLNDD6fBVPxDXhuL .arrowheadPath{fill:#333333;}#mermaid-svg-mLNDD6fBVPxDXhuL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mLNDD6fBVPxDXhuL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mLNDD6fBVPxDXhuL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mLNDD6fBVPxDXhuL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mLNDD6fBVPxDXhuL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mLNDD6fBVPxDXhuL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster text{fill:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL .cluster span{color:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mLNDD6fBVPxDXhuL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mLNDD6fBVPxDXhuL rect.text{fill:none;stroke-width:0;}#mermaid-svg-mLNDD6fBVPxDXhuL .icon-shape,#mermaid-svg-mLNDD6fBVPxDXhuL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mLNDD6fBVPxDXhuL .icon-shape p,#mermaid-svg-mLNDD6fBVPxDXhuL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mLNDD6fBVPxDXhuL .icon-shape .label rect,#mermaid-svg-mLNDD6fBVPxDXhuL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mLNDD6fBVPxDXhuL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mLNDD6fBVPxDXhuL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mLNDD6fBVPxDXhuL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Bean 作用域
① singleton (默认)全容器只有一个实例★ 最常用- Bean 从单例缓存 singletonObjects 获取- 启动时预加载 (非懒加载)
② prototype每次获取都创建新实例- 每次 getBean() 都是新的- Spring 不管理完整生命周期- 销毁方法不自动回调
③ request (Web)每个 HTTP 请求一个实例- RequestScope- 请求结束自动销毁
④ session (Web)每个 HTTP Session 一个实例- SessionScope- Session 过期自动销毁
⑤ application (Web)每个 ServletContext 一个实例- 类似 singleton,但作用域在 ServletContext 维度
⑥ websocket (Web)每个 WebSocket 连接一个实例- WebSocket 关闭自动销毁
// 作用域配置方式
@Component
@Scope("singleton") // 默认
public class SingletonBean {}
@Component
@Scope("prototype") // 原型
public class PrototypeBean {}
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) // 请求作用域
public class RequestBean {}
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) // 会话作用域
public class SessionBean {}
Singleton 依赖 Prototype 的问题:如果 Singleton Bean 内部注入了 Prototype Bean,由于 Singleton 只创建一次,其内部的 Prototype Bean 也只会被注入一次。解决方案:使用 @Lookup 注解或 ObjectFactory 动态获取。
2.3 依赖注入详解
2.3.1 自动装配模式 (AutowireMode)
// AbstractBeanDefinition.java 中定义的常量
public static final int AUTOWIRE_NO = 0; // 默认 – 不自动装配
public static final int AUTOWIRE_BY_NAME = 1; // byName – 按名称自动装配
public static final int AUTOWIRE_BY_TYPE = 2; // byType – 按类型自动装配
public static final int AUTOWIRE_CONSTRUCTOR = 3; // 构造器自动装配
2.3.2 @Autowired vs @Resource vs @Inject
#mermaid-svg-jnTdvhoyAt1GryI9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jnTdvhoyAt1GryI9 .error-icon{fill:#552222;}#mermaid-svg-jnTdvhoyAt1GryI9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jnTdvhoyAt1GryI9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jnTdvhoyAt1GryI9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jnTdvhoyAt1GryI9 .marker.cross{stroke:#333333;}#mermaid-svg-jnTdvhoyAt1GryI9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jnTdvhoyAt1GryI9 p{margin:0;}#mermaid-svg-jnTdvhoyAt1GryI9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster-label text{fill:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster-label span{color:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster-label span p{background-color:transparent;}#mermaid-svg-jnTdvhoyAt1GryI9 .label text,#mermaid-svg-jnTdvhoyAt1GryI9 span{fill:#333;color:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 .node rect,#mermaid-svg-jnTdvhoyAt1GryI9 .node circle,#mermaid-svg-jnTdvhoyAt1GryI9 .node ellipse,#mermaid-svg-jnTdvhoyAt1GryI9 .node polygon,#mermaid-svg-jnTdvhoyAt1GryI9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jnTdvhoyAt1GryI9 .rough-node .label text,#mermaid-svg-jnTdvhoyAt1GryI9 .node .label text,#mermaid-svg-jnTdvhoyAt1GryI9 .image-shape .label,#mermaid-svg-jnTdvhoyAt1GryI9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-jnTdvhoyAt1GryI9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jnTdvhoyAt1GryI9 .rough-node .label,#mermaid-svg-jnTdvhoyAt1GryI9 .node .label,#mermaid-svg-jnTdvhoyAt1GryI9 .image-shape .label,#mermaid-svg-jnTdvhoyAt1GryI9 .icon-shape .label{text-align:center;}#mermaid-svg-jnTdvhoyAt1GryI9 .node.clickable{cursor:pointer;}#mermaid-svg-jnTdvhoyAt1GryI9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jnTdvhoyAt1GryI9 .arrowheadPath{fill:#333333;}#mermaid-svg-jnTdvhoyAt1GryI9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jnTdvhoyAt1GryI9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jnTdvhoyAt1GryI9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jnTdvhoyAt1GryI9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jnTdvhoyAt1GryI9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jnTdvhoyAt1GryI9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster text{fill:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 .cluster span{color:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jnTdvhoyAt1GryI9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jnTdvhoyAt1GryI9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-jnTdvhoyAt1GryI9 .icon-shape,#mermaid-svg-jnTdvhoyAt1GryI9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jnTdvhoyAt1GryI9 .icon-shape p,#mermaid-svg-jnTdvhoyAt1GryI9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jnTdvhoyAt1GryI9 .icon-shape .label rect,#mermaid-svg-jnTdvhoyAt1GryI9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jnTdvhoyAt1GryI9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jnTdvhoyAt1GryI9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jnTdvhoyAt1GryI9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
三种注入注解对比
@Autowired(Spring 原生)- 默认按类型注入- 配合 @Qualifier 按名称- required=false 可选
@Resource(JSR-250 / Jakarta EE)- 默认按名称注入- name 属性指定名称- type 属性指定类型
@Inject(JSR-330)- 默认按类型注入- @Named 按名称- 无 required 属性- 需额外依赖
// @Autowired 示例
@Service
public class UserService {
// 按类型注入(如果只有一个匹配)
@Autowired
private UserRepository userRepository;
// 按类型 + 按名称限定
@Autowired
@Qualifier("jdbcUserRepository")
private UserRepository jdbcRepo;
// 注入所有匹配类型的 Bean
@Autowired
private List<UserRepository> allRepos;
// 可选依赖(不存在时不报错)
@Autowired(required = false)
private Logger logger;
}
2.3.3 注入方式的处理顺序
#mermaid-svg-asYMa1K2k7Vces2K{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-asYMa1K2k7Vces2K .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-asYMa1K2k7Vces2K .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-asYMa1K2k7Vces2K .error-icon{fill:#552222;}#mermaid-svg-asYMa1K2k7Vces2K .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-asYMa1K2k7Vces2K .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-asYMa1K2k7Vces2K .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-asYMa1K2k7Vces2K .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-asYMa1K2k7Vces2K .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-asYMa1K2k7Vces2K .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-asYMa1K2k7Vces2K .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-asYMa1K2k7Vces2K .marker{fill:#333333;stroke:#333333;}#mermaid-svg-asYMa1K2k7Vces2K .marker.cross{stroke:#333333;}#mermaid-svg-asYMa1K2k7Vces2K svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-asYMa1K2k7Vces2K p{margin:0;}#mermaid-svg-asYMa1K2k7Vces2K .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-asYMa1K2k7Vces2K .cluster-label text{fill:#333;}#mermaid-svg-asYMa1K2k7Vces2K .cluster-label span{color:#333;}#mermaid-svg-asYMa1K2k7Vces2K .cluster-label span p{background-color:transparent;}#mermaid-svg-asYMa1K2k7Vces2K .label text,#mermaid-svg-asYMa1K2k7Vces2K span{fill:#333;color:#333;}#mermaid-svg-asYMa1K2k7Vces2K .node rect,#mermaid-svg-asYMa1K2k7Vces2K .node circle,#mermaid-svg-asYMa1K2k7Vces2K .node ellipse,#mermaid-svg-asYMa1K2k7Vces2K .node polygon,#mermaid-svg-asYMa1K2k7Vces2K .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-asYMa1K2k7Vces2K .rough-node .label text,#mermaid-svg-asYMa1K2k7Vces2K .node .label text,#mermaid-svg-asYMa1K2k7Vces2K .image-shape .label,#mermaid-svg-asYMa1K2k7Vces2K .icon-shape .label{text-anchor:middle;}#mermaid-svg-asYMa1K2k7Vces2K .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-asYMa1K2k7Vces2K .rough-node .label,#mermaid-svg-asYMa1K2k7Vces2K .node .label,#mermaid-svg-asYMa1K2k7Vces2K .image-shape .label,#mermaid-svg-asYMa1K2k7Vces2K .icon-shape .label{text-align:center;}#mermaid-svg-asYMa1K2k7Vces2K .node.clickable{cursor:pointer;}#mermaid-svg-asYMa1K2k7Vces2K .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-asYMa1K2k7Vces2K .arrowheadPath{fill:#333333;}#mermaid-svg-asYMa1K2k7Vces2K .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-asYMa1K2k7Vces2K .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-asYMa1K2k7Vces2K .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-asYMa1K2k7Vces2K .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-asYMa1K2k7Vces2K .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-asYMa1K2k7Vces2K .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-asYMa1K2k7Vces2K .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-asYMa1K2k7Vces2K .cluster text{fill:#333;}#mermaid-svg-asYMa1K2k7Vces2K .cluster span{color:#333;}#mermaid-svg-asYMa1K2k7Vces2K div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-asYMa1K2k7Vces2K .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-asYMa1K2k7Vces2K rect.text{fill:none;stroke-width:0;}#mermaid-svg-asYMa1K2k7Vces2K .icon-shape,#mermaid-svg-asYMa1K2k7Vces2K .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-asYMa1K2k7Vces2K .icon-shape p,#mermaid-svg-asYMa1K2k7Vces2K .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-asYMa1K2k7Vces2K .icon-shape .label rect,#mermaid-svg-asYMa1K2k7Vces2K .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-asYMa1K2k7Vces2K .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-asYMa1K2k7Vces2K .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-asYMa1K2k7Vces2K :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
Bean 实例化后 → populateBean()
BeanDefinition中指定了 autowireMode ?(AUTOWIRE_BY_NAME/AUTOWIRE_BY_TYPE)
执行 byName / byType 自动装配(传统 XML 配置方式)
★ 遍历 InstantiationAwareBeanPostProcessor调用 postProcessProperties()
关键处理器:
AutowiredAnnotationBeanPostProcessor处理 @Autowired / @Value / @Inject内部调用 InjectionMetadata.inject()
CommonAnnotationBeanPostProcessor处理 @Resource
PersistenceAnnotationBeanPostProcessor处理 @PersistenceContext / @PersistenceUnit
★ 实际执行注入- 从容器中查找依赖 Bean- 若不存在则创建 (getBean)- 通过反射设置字段值或调用方法
✅ 依赖注入完成
2.4 Bean 的命名与别名
| @Component (无参数) | 类名首字母小写 | UserService → userService |
| @Component("myName") | 使用指定名称 | myName |
| @Service("userSvc") | 使用指定名称 | userSvc |
| @Bean (无参数) | 方法名 | userRepository |
| @Bean("myRepo") | 使用指定名称 | myRepo |
| @Bean(name = {"a", "b"}) | 多个名称,第一个为主名 | 主名 a,别名 b |
| XML <bean id="xxx"> | 使用 id 属性值 | xxx |
| BeanNameGenerator 自定义 | 自定义生成规则 | 任意 |
别名机制示例:
// 方式一: @Bean 声明多个名称
@Bean(name = {"dataSource", "primaryDataSource", "masterDataSource"})
public DataSource dataSource() { ... }
// 方式二: 编程式注册别名
@Component("userService")
public class UserService { }
@Configuration
public class AppConfig implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) {
((BeanDefinitionRegistry) beanFactory)
.registerAlias("userService", "uSvc");
}
}
2.5 FactoryBean vs BeanFactory
这是一个经典面试题:
#mermaid-svg-iuT5eRo5dr6mh3Xy{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iuT5eRo5dr6mh3Xy .error-icon{fill:#552222;}#mermaid-svg-iuT5eRo5dr6mh3Xy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iuT5eRo5dr6mh3Xy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .marker.cross{stroke:#333333;}#mermaid-svg-iuT5eRo5dr6mh3Xy svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iuT5eRo5dr6mh3Xy p{margin:0;}#mermaid-svg-iuT5eRo5dr6mh3Xy .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster-label text{fill:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster-label span{color:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster-label span p{background-color:transparent;}#mermaid-svg-iuT5eRo5dr6mh3Xy .label text,#mermaid-svg-iuT5eRo5dr6mh3Xy span{fill:#333;color:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .node rect,#mermaid-svg-iuT5eRo5dr6mh3Xy .node circle,#mermaid-svg-iuT5eRo5dr6mh3Xy .node ellipse,#mermaid-svg-iuT5eRo5dr6mh3Xy .node polygon,#mermaid-svg-iuT5eRo5dr6mh3Xy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .rough-node .label text,#mermaid-svg-iuT5eRo5dr6mh3Xy .node .label text,#mermaid-svg-iuT5eRo5dr6mh3Xy .image-shape .label,#mermaid-svg-iuT5eRo5dr6mh3Xy .icon-shape .label{text-anchor:middle;}#mermaid-svg-iuT5eRo5dr6mh3Xy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .rough-node .label,#mermaid-svg-iuT5eRo5dr6mh3Xy .node .label,#mermaid-svg-iuT5eRo5dr6mh3Xy .image-shape .label,#mermaid-svg-iuT5eRo5dr6mh3Xy .icon-shape .label{text-align:center;}#mermaid-svg-iuT5eRo5dr6mh3Xy .node.clickable{cursor:pointer;}#mermaid-svg-iuT5eRo5dr6mh3Xy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .arrowheadPath{fill:#333333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iuT5eRo5dr6mh3Xy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iuT5eRo5dr6mh3Xy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iuT5eRo5dr6mh3Xy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster text{fill:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy .cluster span{color:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iuT5eRo5dr6mh3Xy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iuT5eRo5dr6mh3Xy rect.text{fill:none;stroke-width:0;}#mermaid-svg-iuT5eRo5dr6mh3Xy .icon-shape,#mermaid-svg-iuT5eRo5dr6mh3Xy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iuT5eRo5dr6mh3Xy .icon-shape p,#mermaid-svg-iuT5eRo5dr6mh3Xy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iuT5eRo5dr6mh3Xy .icon-shape .label rect,#mermaid-svg-iuT5eRo5dr6mh3Xy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iuT5eRo5dr6mh3Xy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iuT5eRo5dr6mh3Xy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iuT5eRo5dr6mh3Xy :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
FactoryBean vs BeanFactory
FactoryBean- 是一个生产 Bean 的工厂- 本身是一个 Bean- 用于创建复杂对象- getObject() 返回生产的 Bean- &beanName 获取 FactoryBean 自身
BeanFactory- 是整个 IoC 容器- 管理所有 Bean 的生命周期- 是 Spring 框架的基础设施- 不是普通的 Bean
// FactoryBean 示例:创建复杂对象
@Component("myBatisSqlSessionFactory")
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory> {
private DataSource dataSource;
@Override
public SqlSessionFactory getObject() throws Exception {
// 复杂创建逻辑
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
return sessionFactoryBean.getObject();
}
@Override
public Class<?> getObjectType() {
return SqlSessionFactory.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
// 获取 FactoryBean 产生的对象 vs FactoryBean 自身
@Autowired
private SqlSessionFactory sqlSessionFactory; // ← getObject() 的产物
@Autowired
@Qualifier("&myBatisSqlSessionFactory")
private SqlSessionFactoryBean factoryBean; // ← FactoryBean 自身
2.6 循环依赖问题
2.6.1 什么是循环依赖
A 依赖 B → B 依赖 C → C 依赖 A
例如:
@Service
public class A { @Autowired private B b; }
@Service
public class B { @Autowired private C c; }
@Service
public class C { @Autowired private A a; }
2.6.2 循环依赖解决的前提条件
#mermaid-svg-e8BYO1J0oIGmmjWt{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-e8BYO1J0oIGmmjWt .error-icon{fill:#552222;}#mermaid-svg-e8BYO1J0oIGmmjWt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e8BYO1J0oIGmmjWt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e8BYO1J0oIGmmjWt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e8BYO1J0oIGmmjWt .marker.cross{stroke:#333333;}#mermaid-svg-e8BYO1J0oIGmmjWt svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e8BYO1J0oIGmmjWt p{margin:0;}#mermaid-svg-e8BYO1J0oIGmmjWt .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster-label text{fill:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster-label span{color:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster-label span p{background-color:transparent;}#mermaid-svg-e8BYO1J0oIGmmjWt .label text,#mermaid-svg-e8BYO1J0oIGmmjWt span{fill:#333;color:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt .node rect,#mermaid-svg-e8BYO1J0oIGmmjWt .node circle,#mermaid-svg-e8BYO1J0oIGmmjWt .node ellipse,#mermaid-svg-e8BYO1J0oIGmmjWt .node polygon,#mermaid-svg-e8BYO1J0oIGmmjWt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-e8BYO1J0oIGmmjWt .rough-node .label text,#mermaid-svg-e8BYO1J0oIGmmjWt .node .label text,#mermaid-svg-e8BYO1J0oIGmmjWt .image-shape .label,#mermaid-svg-e8BYO1J0oIGmmjWt .icon-shape .label{text-anchor:middle;}#mermaid-svg-e8BYO1J0oIGmmjWt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-e8BYO1J0oIGmmjWt .rough-node .label,#mermaid-svg-e8BYO1J0oIGmmjWt .node .label,#mermaid-svg-e8BYO1J0oIGmmjWt .image-shape .label,#mermaid-svg-e8BYO1J0oIGmmjWt .icon-shape .label{text-align:center;}#mermaid-svg-e8BYO1J0oIGmmjWt .node.clickable{cursor:pointer;}#mermaid-svg-e8BYO1J0oIGmmjWt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-e8BYO1J0oIGmmjWt .arrowheadPath{fill:#333333;}#mermaid-svg-e8BYO1J0oIGmmjWt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-e8BYO1J0oIGmmjWt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-e8BYO1J0oIGmmjWt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8BYO1J0oIGmmjWt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-e8BYO1J0oIGmmjWt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8BYO1J0oIGmmjWt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster text{fill:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt .cluster span{color:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-e8BYO1J0oIGmmjWt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-e8BYO1J0oIGmmjWt rect.text{fill:none;stroke-width:0;}#mermaid-svg-e8BYO1J0oIGmmjWt .icon-shape,#mermaid-svg-e8BYO1J0oIGmmjWt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8BYO1J0oIGmmjWt .icon-shape p,#mermaid-svg-e8BYO1J0oIGmmjWt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-e8BYO1J0oIGmmjWt .icon-shape .label rect,#mermaid-svg-e8BYO1J0oIGmmjWt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8BYO1J0oIGmmjWt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-e8BYO1J0oIGmmjWt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-e8BYO1J0oIGmmjWt :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
✅ Spring 能解决的情况:
单例 Bean 的 Setter/Field 注入
循环依赖发生在不同的 Bean 之间
不是构造器注入
❌ Spring 不能解决的情况:
原型 (prototype) 作用域的循环依赖
构造器注入的循环依赖
Spring Boot 3 默认禁用循环依赖(setAllowCircularReferences(false))若需要: spring.main.allow-circular-references=true
2.6.3 解决方案
| 重新设计 | 消除循环依赖,引入第三个类 | ⭐⭐⭐⭐⭐ 最佳 |
| @Lazy 注解 | @Autowired @Lazy private A a; 使用代理延迟加载 | ⭐⭐⭐⭐ |
| Setter/Field 注入 | 改为非构造器注入方式 | ⭐⭐⭐ |
| ObjectFactory/ObjectProvider | @Autowired private ObjectProvider<A> aProvider; 延迟获取 | ⭐⭐⭐⭐ |
| @PostConstruct + setter | 构造器注入后,在 @PostConstruct 中手动设置另一个 | ⭐⭐ |
| spring.main.allow-circular-references=true | 回退到旧行为 | ⭐ 不推荐 |
第二部分:源码分析
3. Spring IoC 容器概述
3.1 什么是 IoC 容器
Spring IoC(Inversion of Control)容器是 Spring 框架的核心,负责:
- Bean 定义加载:读取 XML、注解、Java Config 等配置,解析为 BeanDefinition
- Bean 实例化:通过反射创建 Bean 实例
- 依赖注入:自动装配 Bean 之间的依赖关系
- Bean 生命周期管理:从初始化到销毁的完整生命周期回调
3.2 容器启动的整体阶段
#mermaid-svg-GdnInAFyGnRYdeP7{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GdnInAFyGnRYdeP7 .error-icon{fill:#552222;}#mermaid-svg-GdnInAFyGnRYdeP7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GdnInAFyGnRYdeP7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GdnInAFyGnRYdeP7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GdnInAFyGnRYdeP7 .marker.cross{stroke:#333333;}#mermaid-svg-GdnInAFyGnRYdeP7 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GdnInAFyGnRYdeP7 p{margin:0;}#mermaid-svg-GdnInAFyGnRYdeP7 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster-label text{fill:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster-label span{color:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster-label span p{background-color:transparent;}#mermaid-svg-GdnInAFyGnRYdeP7 .label text,#mermaid-svg-GdnInAFyGnRYdeP7 span{fill:#333;color:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 .node rect,#mermaid-svg-GdnInAFyGnRYdeP7 .node circle,#mermaid-svg-GdnInAFyGnRYdeP7 .node ellipse,#mermaid-svg-GdnInAFyGnRYdeP7 .node polygon,#mermaid-svg-GdnInAFyGnRYdeP7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GdnInAFyGnRYdeP7 .rough-node .label text,#mermaid-svg-GdnInAFyGnRYdeP7 .node .label text,#mermaid-svg-GdnInAFyGnRYdeP7 .image-shape .label,#mermaid-svg-GdnInAFyGnRYdeP7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-GdnInAFyGnRYdeP7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GdnInAFyGnRYdeP7 .rough-node .label,#mermaid-svg-GdnInAFyGnRYdeP7 .node .label,#mermaid-svg-GdnInAFyGnRYdeP7 .image-shape .label,#mermaid-svg-GdnInAFyGnRYdeP7 .icon-shape .label{text-align:center;}#mermaid-svg-GdnInAFyGnRYdeP7 .node.clickable{cursor:pointer;}#mermaid-svg-GdnInAFyGnRYdeP7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GdnInAFyGnRYdeP7 .arrowheadPath{fill:#333333;}#mermaid-svg-GdnInAFyGnRYdeP7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GdnInAFyGnRYdeP7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GdnInAFyGnRYdeP7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GdnInAFyGnRYdeP7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GdnInAFyGnRYdeP7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GdnInAFyGnRYdeP7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster text{fill:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 .cluster span{color:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GdnInAFyGnRYdeP7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GdnInAFyGnRYdeP7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-GdnInAFyGnRYdeP7 .icon-shape,#mermaid-svg-GdnInAFyGnRYdeP7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GdnInAFyGnRYdeP7 .icon-shape p,#mermaid-svg-GdnInAFyGnRYdeP7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GdnInAFyGnRYdeP7 .icon-shape .label rect,#mermaid-svg-GdnInAFyGnRYdeP7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GdnInAFyGnRYdeP7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GdnInAFyGnRYdeP7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GdnInAFyGnRYdeP7 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
📦 阶段1BeanDefinition 加载(XML/注解/Java Config → BeanDefinition)
⚙️ 阶段2BeanFactory 后置处理(BeanDefinition 增强/修改)
🔧 阶段3BeanPostProcessor 注册(Bean 实例化的拦截器)
🌱 阶段4Bean 实例化(单例 Bean 创建 + 依赖注入)
✅ 阶段5容器就绪(事件发布 + 生命周期回调)
4. 容器启动总览:refresh() 方法
4.1 概览图
#mermaid-svg-ZGYDVxUh4aAxZP3r{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZGYDVxUh4aAxZP3r .error-icon{fill:#552222;}#mermaid-svg-ZGYDVxUh4aAxZP3r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZGYDVxUh4aAxZP3r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .marker.cross{stroke:#333333;}#mermaid-svg-ZGYDVxUh4aAxZP3r svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZGYDVxUh4aAxZP3r p{margin:0;}#mermaid-svg-ZGYDVxUh4aAxZP3r .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster-label text{fill:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster-label span{color:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster-label span p{background-color:transparent;}#mermaid-svg-ZGYDVxUh4aAxZP3r .label text,#mermaid-svg-ZGYDVxUh4aAxZP3r span{fill:#333;color:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .node rect,#mermaid-svg-ZGYDVxUh4aAxZP3r .node circle,#mermaid-svg-ZGYDVxUh4aAxZP3r .node ellipse,#mermaid-svg-ZGYDVxUh4aAxZP3r .node polygon,#mermaid-svg-ZGYDVxUh4aAxZP3r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .rough-node .label text,#mermaid-svg-ZGYDVxUh4aAxZP3r .node .label text,#mermaid-svg-ZGYDVxUh4aAxZP3r .image-shape .label,#mermaid-svg-ZGYDVxUh4aAxZP3r .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZGYDVxUh4aAxZP3r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .rough-node .label,#mermaid-svg-ZGYDVxUh4aAxZP3r .node .label,#mermaid-svg-ZGYDVxUh4aAxZP3r .image-shape .label,#mermaid-svg-ZGYDVxUh4aAxZP3r .icon-shape .label{text-align:center;}#mermaid-svg-ZGYDVxUh4aAxZP3r .node.clickable{cursor:pointer;}#mermaid-svg-ZGYDVxUh4aAxZP3r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .arrowheadPath{fill:#333333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZGYDVxUh4aAxZP3r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZGYDVxUh4aAxZP3r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZGYDVxUh4aAxZP3r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster text{fill:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r .cluster span{color:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZGYDVxUh4aAxZP3r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZGYDVxUh4aAxZP3r rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZGYDVxUh4aAxZP3r .icon-shape,#mermaid-svg-ZGYDVxUh4aAxZP3r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZGYDVxUh4aAxZP3r .icon-shape p,#mermaid-svg-ZGYDVxUh4aAxZP3r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZGYDVxUh4aAxZP3r .icon-shape .label rect,#mermaid-svg-ZGYDVxUh4aAxZP3r .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZGYDVxUh4aAxZP3r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZGYDVxUh4aAxZP3r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZGYDVxUh4aAxZP3r :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
▶️ refresh() 入口synchronized(this.startupShutdownMonitor)
① prepareRefresh()- 记录启动时间- 设置 active 标志- 初始化 PropertySources- 校验必要属性
② obtainFreshBeanFactory()- 刷新 BeanFactory (子类实现)- 返回 ConfigurableListableBeanFactory- ★ XML: 加载解析 XML 文件- ★ 注解: 已在上层完成 (GenericApplicationContext)
③ prepareBeanFactory(beanFactory)- 设置 ClassLoader- 注册默认的 BeanPostProcessor- 注册默认的 Environment Bean- 忽略 Aware 接口的自动装配
④ postProcessBeanFactory(beanFactory)- ★ 模板方法,留给子类扩展- 子类可以在此注册特殊的 BeanPostProcessor- (Web 容器在此注册 request/session scope)
⑤ ★ invokeBeanFactoryPostProcessors(beanFactory) ★- 执行所有 BeanFactoryPostProcessor- ConfigurationClassPostProcessor 解析 @Configuration- 触发 @ComponentScan 扫描- 处理 @Import、@Bean 等- ★ 所有 BeanDefinition 在此完成注册
⑥ registerBeanPostProcessors(beanFactory)- 注册 BeanPostProcessor 实现类- 按 PriorityOrdered → Ordered → 普通 排序- ★ 这些处理器将在 Bean 实例化时被调用
⑦ initMessageSource()- 初始化国际化消息源- 查找名为 messageSource 的 Bean- 默认 DelegatingMessageSource
⑧ initApplicationEventMulticaster()- 初始化事件广播器- 查找名为 applicationEventMulticaster 的 Bean- 默认 SimpleApplicationEventMulticaster
⑨ onRefresh()- ★ 模板方法,留给子类- Spring Boot: createWebServer()- 普通 Spring: 空实现
⑩ registerListeners()- 注册 ApplicationListener Bean- 广播早期事件 (earlyApplicationEvents)
⑪ ★ finishBeanFactoryInitialization(beanFactory) ★- 实例化所有非懒加载单例 Bean- ★ getBean() 触发完整 Bean 生命周期- 触发 SmartInitializingSingleton 回调
⑫ finishRefresh()- 清除 Resource 缓存- 初始化 LifecycleProcessor- 启动 Lifecycle Bean- 发布 ContextRefreshedEvent
✅ refresh() 完成容器完全就绪
4.2 源码
// AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// ─── 步骤 1:准备刷新 ───
prepareRefresh();
// ─── 步骤 2:获取 BeanFactory ───
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// ─── 步骤 3:准备 BeanFactory ───
prepareBeanFactory(beanFactory);
try {
// ─── 步骤 4:BeanFactory 后置处理(模板方法) ───
postProcessBeanFactory(beanFactory);
// ─── 步骤 5:调用 BeanFactoryPostProcessor ★核心★ ───
invokeBeanFactoryPostProcessors(beanFactory);
// ─── 步骤 6:注册 BeanPostProcessor ★核心★ ───
registerBeanPostProcessors(beanFactory);
// ─── 步骤 7:初始化消息源 ───
initMessageSource();
// ─── 步骤 8:初始化事件多播器 ───
initApplicationEventMulticaster();
// ─── 步骤 9:onRefresh(模板方法) ───
onRefresh();
// ─── 步骤 10:注册监听器 ───
registerListeners();
// ─── 步骤 11:完成 BeanFactory 初始化 ★核心★ ───
finishBeanFactoryInitialization(beanFactory);
// ─── 步骤 12:完成刷新 ───
finishRefresh();
}
catch (BeansException ex) {
// 清理
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
// 清除反射缓存等公共缓存
resetCommonCaches();
}
}
}
5. 步骤 1:prepareRefresh() — 准备刷新
5.1 流程图
#mermaid-svg-wocgjhdsfWd4ntkT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wocgjhdsfWd4ntkT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wocgjhdsfWd4ntkT .error-icon{fill:#552222;}#mermaid-svg-wocgjhdsfWd4ntkT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wocgjhdsfWd4ntkT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wocgjhdsfWd4ntkT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wocgjhdsfWd4ntkT .marker.cross{stroke:#333333;}#mermaid-svg-wocgjhdsfWd4ntkT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wocgjhdsfWd4ntkT p{margin:0;}#mermaid-svg-wocgjhdsfWd4ntkT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-wocgjhdsfWd4ntkT .cluster-label text{fill:#333;}#mermaid-svg-wocgjhdsfWd4ntkT .cluster-label span{color:#333;}#mermaid-svg-wocgjhdsfWd4ntkT .cluster-label span p{background-color:transparent;}#mermaid-svg-wocgjhdsfWd4ntkT .label text,#mermaid-svg-wocgjhdsfWd4ntkT span{fill:#333;color:#333;}#mermaid-svg-wocgjhdsfWd4ntkT .node rect,#mermaid-svg-wocgjhdsfWd4ntkT .node circle,#mermaid-svg-wocgjhdsfWd4ntkT .node ellipse,#mermaid-svg-wocgjhdsfWd4ntkT .node polygon,#mermaid-svg-wocgjhdsfWd4ntkT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wocgjhdsfWd4ntkT .rough-node .label text,#mermaid-svg-wocgjhdsfWd4ntkT .node .label text,#mermaid-svg-wocgjhdsfWd4ntkT .image-shape .label,#mermaid-svg-wocgjhdsfWd4ntkT .icon-shape .label{text-anchor:middle;}#mermaid-svg-wocgjhdsfWd4ntkT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wocgjhdsfWd4ntkT .rough-node .label,#mermaid-svg-wocgjhdsfWd4ntkT .node .label,#mermaid-svg-wocgjhdsfWd4ntkT .image-shape .label,#mermaid-svg-wocgjhdsfWd4ntkT .icon-shape .label{text-align:center;}#mermaid-svg-wocgjhdsfWd4ntkT .node.clickable{cursor:pointer;}#mermaid-svg-wocgjhdsfWd4ntkT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wocgjhdsfWd4ntkT .arrowheadPath{fill:#333333;}#mermaid-svg-wocgjhdsfWd4ntkT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wocgjhdsfWd4ntkT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wocgjhdsfWd4ntkT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wocgjhdsfWd4ntkT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wocgjhdsfWd4ntkT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wocgjhdsfWd4ntkT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wocgjhdsfWd4ntkT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wocgjhdsfWd4ntkT .cluster text{fill:#333;}#mermaid-svg-wocgjhdsfWd4ntkT .cluster span{color:#333;}#mermaid-svg-wocgjhdsfWd4ntkT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wocgjhdsfWd4ntkT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wocgjhdsfWd4ntkT rect.text{fill:none;stroke-width:0;}#mermaid-svg-wocgjhdsfWd4ntkT .icon-shape,#mermaid-svg-wocgjhdsfWd4ntkT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wocgjhdsfWd4ntkT .icon-shape p,#mermaid-svg-wocgjhdsfWd4ntkT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wocgjhdsfWd4ntkT .icon-shape .label rect,#mermaid-svg-wocgjhdsfWd4ntkT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wocgjhdsfWd4ntkT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wocgjhdsfWd4ntkT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wocgjhdsfWd4ntkT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
prepareRefresh()
this.startupDate = System.currentTimeMillis()记录启动时间戳
this.closed.set(false)this.active.set(true)设置状态标志
initPropertySources()★ 模板方法,子类可初始化自定义属性源(如 Web 应用初始化 ServletContext 属性)
getEnvironment().validateRequiredProperties()★ 校验标记为 required 的属性是否存在若缺失则抛出 MissingRequiredPropertiesException
this.earlyApplicationEvents = new LinkedHashSet<>()保存早期事件(广播器未就绪时发布的事件)
✅ 刷新准备完成
5.2 源码
// AbstractApplicationContext.java
protected void prepareRefresh() {
// 1. 记录容器启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
logger.debug("Refreshing " + this);
}
// 2. 初始化属性源(模板方法,留给子类覆盖)
initPropertySources();
// 3. 校验必要属性
getEnvironment().validateRequiredProperties();
// 4. 创建早期事件集合(存储监听器注册前发布的事件)
this.earlyApplicationEvents = new LinkedHashSet<>();
}
initPropertySources() 扩展点:
// 例如:GenericWebApplicationContext 中的实现
@Override
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(
getServletContext(), getServletConfig());
}
}
6. 步骤 2:obtainFreshBeanFactory() — 获取 BeanFactory
6.1 流程图
#mermaid-svg-c9sxRBFSXEynQWG3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-c9sxRBFSXEynQWG3 .error-icon{fill:#552222;}#mermaid-svg-c9sxRBFSXEynQWG3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-c9sxRBFSXEynQWG3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-c9sxRBFSXEynQWG3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-c9sxRBFSXEynQWG3 .marker.cross{stroke:#333333;}#mermaid-svg-c9sxRBFSXEynQWG3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-c9sxRBFSXEynQWG3 p{margin:0;}#mermaid-svg-c9sxRBFSXEynQWG3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster-label text{fill:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster-label span{color:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster-label span p{background-color:transparent;}#mermaid-svg-c9sxRBFSXEynQWG3 .label text,#mermaid-svg-c9sxRBFSXEynQWG3 span{fill:#333;color:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 .node rect,#mermaid-svg-c9sxRBFSXEynQWG3 .node circle,#mermaid-svg-c9sxRBFSXEynQWG3 .node ellipse,#mermaid-svg-c9sxRBFSXEynQWG3 .node polygon,#mermaid-svg-c9sxRBFSXEynQWG3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-c9sxRBFSXEynQWG3 .rough-node .label text,#mermaid-svg-c9sxRBFSXEynQWG3 .node .label text,#mermaid-svg-c9sxRBFSXEynQWG3 .image-shape .label,#mermaid-svg-c9sxRBFSXEynQWG3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-c9sxRBFSXEynQWG3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-c9sxRBFSXEynQWG3 .rough-node .label,#mermaid-svg-c9sxRBFSXEynQWG3 .node .label,#mermaid-svg-c9sxRBFSXEynQWG3 .image-shape .label,#mermaid-svg-c9sxRBFSXEynQWG3 .icon-shape .label{text-align:center;}#mermaid-svg-c9sxRBFSXEynQWG3 .node.clickable{cursor:pointer;}#mermaid-svg-c9sxRBFSXEynQWG3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-c9sxRBFSXEynQWG3 .arrowheadPath{fill:#333333;}#mermaid-svg-c9sxRBFSXEynQWG3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-c9sxRBFSXEynQWG3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-c9sxRBFSXEynQWG3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c9sxRBFSXEynQWG3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-c9sxRBFSXEynQWG3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c9sxRBFSXEynQWG3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster text{fill:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 .cluster span{color:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-c9sxRBFSXEynQWG3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-c9sxRBFSXEynQWG3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-c9sxRBFSXEynQWG3 .icon-shape,#mermaid-svg-c9sxRBFSXEynQWG3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c9sxRBFSXEynQWG3 .icon-shape p,#mermaid-svg-c9sxRBFSXEynQWG3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-c9sxRBFSXEynQWG3 .icon-shape .label rect,#mermaid-svg-c9sxRBFSXEynQWG3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c9sxRBFSXEynQWG3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-c9sxRBFSXEynQWG3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-c9sxRBFSXEynQWG3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
AbstractRefreshableApplicationContext(XML 模式)
GenericApplicationContext(注解模式)
obtainFreshBeanFactory()
refreshBeanFactory()★ 抽象方法,由子类实现
子类类型 ?
1. 若已有 BeanFactory,销毁并关闭2. 创建 DefaultListableBeanFactory3. 加载 BeanDefinition (XmlBeanDefinitionReader 解析 XML)4. 设置 BeanFactory 的 ID
1. CAS 设置 refreshed 标志(防止重复刷新)2. BeanFactory 已在构造时创建(AnnotatedBeanDefinitionReader 解析注解配置类)
return getBeanFactory()返回 ConfigurableListableBeanFactory
✅ BeanFactory 就绪包含所有 BeanDefinition
6.2 源码
// AbstractApplicationContext.java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
XML 模式实现 (AbstractRefreshableApplicationContext):
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory); // ★ 加载 XML
this.beanFactory = beanFactory;
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing XML document", ex);
}
}
注解模式实现 (GenericApplicationContext):
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts");
}
this.beanFactory.setSerializationId(getId());
}
注解模式下,BeanFactory(DefaultListableBeanFactory)在 GenericApplicationContext 的构造函数中就已创建:
// GenericApplicationContext.java
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
BeanDefinition 的注册在 AnnotationConfigApplicationContext 的构造函数中完成:
// AnnotationConfigApplicationContext.java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh(); // ← 随即调用 refresh()
}
7. 步骤 3:prepareBeanFactory() — 准备 BeanFactory
7.1 流程图
#mermaid-svg-X5Gm2gNX5d9x26Oi{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-X5Gm2gNX5d9x26Oi .error-icon{fill:#552222;}#mermaid-svg-X5Gm2gNX5d9x26Oi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-X5Gm2gNX5d9x26Oi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .marker.cross{stroke:#333333;}#mermaid-svg-X5Gm2gNX5d9x26Oi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-X5Gm2gNX5d9x26Oi p{margin:0;}#mermaid-svg-X5Gm2gNX5d9x26Oi .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster-label text{fill:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster-label span{color:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster-label span p{background-color:transparent;}#mermaid-svg-X5Gm2gNX5d9x26Oi .label text,#mermaid-svg-X5Gm2gNX5d9x26Oi span{fill:#333;color:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .node rect,#mermaid-svg-X5Gm2gNX5d9x26Oi .node circle,#mermaid-svg-X5Gm2gNX5d9x26Oi .node ellipse,#mermaid-svg-X5Gm2gNX5d9x26Oi .node polygon,#mermaid-svg-X5Gm2gNX5d9x26Oi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .rough-node .label text,#mermaid-svg-X5Gm2gNX5d9x26Oi .node .label text,#mermaid-svg-X5Gm2gNX5d9x26Oi .image-shape .label,#mermaid-svg-X5Gm2gNX5d9x26Oi .icon-shape .label{text-anchor:middle;}#mermaid-svg-X5Gm2gNX5d9x26Oi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .rough-node .label,#mermaid-svg-X5Gm2gNX5d9x26Oi .node .label,#mermaid-svg-X5Gm2gNX5d9x26Oi .image-shape .label,#mermaid-svg-X5Gm2gNX5d9x26Oi .icon-shape .label{text-align:center;}#mermaid-svg-X5Gm2gNX5d9x26Oi .node.clickable{cursor:pointer;}#mermaid-svg-X5Gm2gNX5d9x26Oi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .arrowheadPath{fill:#333333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X5Gm2gNX5d9x26Oi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-X5Gm2gNX5d9x26Oi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X5Gm2gNX5d9x26Oi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster text{fill:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi .cluster span{color:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-X5Gm2gNX5d9x26Oi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-X5Gm2gNX5d9x26Oi rect.text{fill:none;stroke-width:0;}#mermaid-svg-X5Gm2gNX5d9x26Oi .icon-shape,#mermaid-svg-X5Gm2gNX5d9x26Oi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X5Gm2gNX5d9x26Oi .icon-shape p,#mermaid-svg-X5Gm2gNX5d9x26Oi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-X5Gm2gNX5d9x26Oi .icon-shape .label rect,#mermaid-svg-X5Gm2gNX5d9x26Oi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X5Gm2gNX5d9x26Oi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-X5Gm2gNX5d9x26Oi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-X5Gm2gNX5d9x26Oi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
prepareBeanFactory(beanFactory)
setBeanClassLoader(getClassLoader())设置类加载器
setBeanExpressionResolver( StandardBeanExpressionResolver)设置 SpEL 表达式解析器用于解析 #{…} 表达式
addPropertyEditorRegistrar( ResourceEditorRegistrar)注册属性编辑器用于将 String 转换为 Resource/File/URL 等
addBeanPostProcessor( ApplicationContextAwareProcessor)★ 注册 Aware 回调处理器处理 EnvironmentAware、ApplicationContextAware 等 6 个接口
ignoreDependencyInterface( EnvironmentAware, ApplicationContextAware, …)★ 忽略这些 Aware 接口的自动装配(它们由 ApplicationContextAwareProcessor 手动注入)
registerResolvableDependency()注册可解析依赖- BeanFactory → 当前 BeanFactory- ResourceLoader → 当前 ApplicationContext- ApplicationContext → 当前 ApplicationContext- ApplicationEventPublisher → 当前 ApplicationContext
addBeanPostProcessor( ApplicationListenerDetector)★ 注册 ApplicationListener 检测器在 Bean 初始化后,若为 ApplicationListener 则注册到事件多播器
registerSingleton()注册环境相关单例 Bean:- environment: ConfigurableEnvironment- systemProperties: Map- systemEnvironment: Map
✅ BeanFactory 准备完成
7.2 源码
// AbstractApplicationContext.java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 1. 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 2. 设置 SpEL 表达式解析器
if (!NativeDetector.inNativeImage()) {
beanFactory.setBeanExpressionResolver(
new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 3. 注册属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 4. ★ 注册 ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 5. ★ 忽略以下 Aware 接口的自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartup.class);
// 6. 注册可解析依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 7. ★ 注册 ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 8. LoadTimeWeaver
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(
new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 9. 注册环境相关单例 Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,
getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME,
getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME,
getApplicationStartup());
}
}
8. 步骤 4:postProcessBeanFactory() — BeanFactory 后置处理
8.1 说明
这是模板方法,AbstractApplicationContext 中为空实现,由子类覆盖。
// AbstractApplicationContext.java
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 空实现,留给子类扩展
}
8.2 Spring Boot Web 容器中的实现
// ServletWebServerApplicationContext.java (Spring Boot)
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(
new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes(); // ★ 注册 request、session、application scope
}
9. 步骤 5:invokeBeanFactoryPostProcessors() — 调用 BeanFactory 后置处理器 ★★★
9.1 概述
这是 Spring 容器启动过程中最核心、最复杂的步骤。它负责:
- 执行所有 BeanFactoryPostProcessor(包括 BeanDefinitionRegistryPostProcessor)
- ConfigurationClassPostProcessor 在此解析 @Configuration、@ComponentScan、@Import、@Bean 等
- 自动配置在此生效(Spring Boot 通过 AutoConfigurationImportSelector 导入配置类)
- 最终所有 BeanDefinition 注册完成
9.2 整体流程图
#mermaid-svg-mPpjKAtsCBNYt71L{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mPpjKAtsCBNYt71L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mPpjKAtsCBNYt71L .error-icon{fill:#552222;}#mermaid-svg-mPpjKAtsCBNYt71L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mPpjKAtsCBNYt71L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mPpjKAtsCBNYt71L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mPpjKAtsCBNYt71L .marker.cross{stroke:#333333;}#mermaid-svg-mPpjKAtsCBNYt71L svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mPpjKAtsCBNYt71L p{margin:0;}#mermaid-svg-mPpjKAtsCBNYt71L .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-mPpjKAtsCBNYt71L .cluster-label text{fill:#333;}#mermaid-svg-mPpjKAtsCBNYt71L .cluster-label span{color:#333;}#mermaid-svg-mPpjKAtsCBNYt71L .cluster-label span p{background-color:transparent;}#mermaid-svg-mPpjKAtsCBNYt71L .label text,#mermaid-svg-mPpjKAtsCBNYt71L span{fill:#333;color:#333;}#mermaid-svg-mPpjKAtsCBNYt71L .node rect,#mermaid-svg-mPpjKAtsCBNYt71L .node circle,#mermaid-svg-mPpjKAtsCBNYt71L .node ellipse,#mermaid-svg-mPpjKAtsCBNYt71L .node polygon,#mermaid-svg-mPpjKAtsCBNYt71L .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mPpjKAtsCBNYt71L .rough-node .label text,#mermaid-svg-mPpjKAtsCBNYt71L .node .label text,#mermaid-svg-mPpjKAtsCBNYt71L .image-shape .label,#mermaid-svg-mPpjKAtsCBNYt71L .icon-shape .label{text-anchor:middle;}#mermaid-svg-mPpjKAtsCBNYt71L .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mPpjKAtsCBNYt71L .rough-node .label,#mermaid-svg-mPpjKAtsCBNYt71L .node .label,#mermaid-svg-mPpjKAtsCBNYt71L .image-shape .label,#mermaid-svg-mPpjKAtsCBNYt71L .icon-shape .label{text-align:center;}#mermaid-svg-mPpjKAtsCBNYt71L .node.clickable{cursor:pointer;}#mermaid-svg-mPpjKAtsCBNYt71L .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mPpjKAtsCBNYt71L .arrowheadPath{fill:#333333;}#mermaid-svg-mPpjKAtsCBNYt71L .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mPpjKAtsCBNYt71L .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mPpjKAtsCBNYt71L .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mPpjKAtsCBNYt71L .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mPpjKAtsCBNYt71L .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mPpjKAtsCBNYt71L .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mPpjKAtsCBNYt71L .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mPpjKAtsCBNYt71L .cluster text{fill:#333;}#mermaid-svg-mPpjKAtsCBNYt71L .cluster span{color:#333;}#mermaid-svg-mPpjKAtsCBNYt71L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mPpjKAtsCBNYt71L .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mPpjKAtsCBNYt71L rect.text{fill:none;stroke-width:0;}#mermaid-svg-mPpjKAtsCBNYt71L .icon-shape,#mermaid-svg-mPpjKAtsCBNYt71L .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mPpjKAtsCBNYt71L .icon-shape p,#mermaid-svg-mPpjKAtsCBNYt71L .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mPpjKAtsCBNYt71L .icon-shape .label rect,#mermaid-svg-mPpjKAtsCBNYt71L .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mPpjKAtsCBNYt71L .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mPpjKAtsCBNYt71L .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mPpjKAtsCBNYt71L :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ConfigurationClassPostProcessor 处理过程
解析所有 @Configuration 类
处理 @ComponentScan扫描指定包下的 @Component/@Service/@Repository/@Controller
处理 @Import- 普通类: 注册为 BeanDefinition- ImportSelector: 调用 selectImports()- ImportBeanDefinitionRegistrar: 注册为 Registrar
处理 @Bean 方法将方法注册为 BeanDefinition
处理 @PropertySource加载 .properties 文件
处理父类/接口的 @Configuration若发现新的配置类,递归处理
invokeBeanFactoryPostProcessors(beanFactory)
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
获取/分类所有 BeanFactoryPostProcessor- BeanDefinitionRegistryPostProcessor (扩展了 BFPP)- 普通 BeanFactoryPostProcessor
★★★ 阶段1: 执行 PriorityOrdered 的BeanDefinitionRegistryPostProcessor当前通常只有: ConfigurationClassPostProcessor ★
★★★ 阶段2: 执行 Ordered 的BeanDefinitionRegistryPostProcessor(如在阶段1中新注册的)
★★★ 阶段3: 执行剩余所有BeanDefinitionRegistryPostProcessor(含前两阶段中新注册的)★ 循环执行直到没有新的注册
阶段4: 执行所有 BeanDefinitionRegistryPostProcessor上的 BeanFactoryPostProcessor 方法(postProcessBeanFactory())
阶段5: 执行剩余的 BeanFactoryPostProcessor(非 BeanDefinitionRegistryPostProcessor)按 PriorityOrdered → Ordered → 普通 排序执行
✅ BeanDefinition 注册完成配置类已解析自动配置已生效
9.3 源码详解
// PostProcessorRegistrationDelegate.java
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry registry) {
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 首先分离手动注册的处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// ─── 阶段 1: 执行实现了 PriorityOrdered 的 ───
// ★ ConfigurationClassPostProcessor 在此执行!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry,
beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// ─── 阶段 2: 执行实现了 Ordered 的 ───
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry,
beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// ─── 阶段 3: 执行所有剩余的(while 循环直到没有新的) ───
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(
currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// ─── 阶段 4: 执行所有 RegistryProcessor 上的 BFPP 回调 ───
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// ─── 阶段 5: 执行非 Registry 的 BeanFactoryPostProcessor ───
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors =
new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
orderedPostProcessors.add(
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors =
new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
9.4 ConfigurationClassPostProcessor — 注解配置解析核心
#mermaid-svg-47GpJU5DpElAQzIq{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-47GpJU5DpElAQzIq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-47GpJU5DpElAQzIq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-47GpJU5DpElAQzIq .error-icon{fill:#552222;}#mermaid-svg-47GpJU5DpElAQzIq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-47GpJU5DpElAQzIq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-47GpJU5DpElAQzIq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-47GpJU5DpElAQzIq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-47GpJU5DpElAQzIq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-47GpJU5DpElAQzIq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-47GpJU5DpElAQzIq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-47GpJU5DpElAQzIq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-47GpJU5DpElAQzIq .marker.cross{stroke:#333333;}#mermaid-svg-47GpJU5DpElAQzIq svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-47GpJU5DpElAQzIq p{margin:0;}#mermaid-svg-47GpJU5DpElAQzIq .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-47GpJU5DpElAQzIq .cluster-label text{fill:#333;}#mermaid-svg-47GpJU5DpElAQzIq .cluster-label span{color:#333;}#mermaid-svg-47GpJU5DpElAQzIq .cluster-label span p{background-color:transparent;}#mermaid-svg-47GpJU5DpElAQzIq .label text,#mermaid-svg-47GpJU5DpElAQzIq span{fill:#333;color:#333;}#mermaid-svg-47GpJU5DpElAQzIq .node rect,#mermaid-svg-47GpJU5DpElAQzIq .node circle,#mermaid-svg-47GpJU5DpElAQzIq .node ellipse,#mermaid-svg-47GpJU5DpElAQzIq .node polygon,#mermaid-svg-47GpJU5DpElAQzIq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-47GpJU5DpElAQzIq .rough-node .label text,#mermaid-svg-47GpJU5DpElAQzIq .node .label text,#mermaid-svg-47GpJU5DpElAQzIq .image-shape .label,#mermaid-svg-47GpJU5DpElAQzIq .icon-shape .label{text-anchor:middle;}#mermaid-svg-47GpJU5DpElAQzIq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-47GpJU5DpElAQzIq .rough-node .label,#mermaid-svg-47GpJU5DpElAQzIq .node .label,#mermaid-svg-47GpJU5DpElAQzIq .image-shape .label,#mermaid-svg-47GpJU5DpElAQzIq .icon-shape .label{text-align:center;}#mermaid-svg-47GpJU5DpElAQzIq .node.clickable{cursor:pointer;}#mermaid-svg-47GpJU5DpElAQzIq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-47GpJU5DpElAQzIq .arrowheadPath{fill:#333333;}#mermaid-svg-47GpJU5DpElAQzIq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-47GpJU5DpElAQzIq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-47GpJU5DpElAQzIq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-47GpJU5DpElAQzIq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-47GpJU5DpElAQzIq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-47GpJU5DpElAQzIq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-47GpJU5DpElAQzIq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-47GpJU5DpElAQzIq .cluster text{fill:#333;}#mermaid-svg-47GpJU5DpElAQzIq .cluster span{color:#333;}#mermaid-svg-47GpJU5DpElAQzIq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-47GpJU5DpElAQzIq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-47GpJU5DpElAQzIq rect.text{fill:none;stroke-width:0;}#mermaid-svg-47GpJU5DpElAQzIq .icon-shape,#mermaid-svg-47GpJU5DpElAQzIq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-47GpJU5DpElAQzIq .icon-shape p,#mermaid-svg-47GpJU5DpElAQzIq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-47GpJU5DpElAQzIq .icon-shape .label rect,#mermaid-svg-47GpJU5DpElAQzIq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-47GpJU5DpElAQzIq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-47GpJU5DpElAQzIq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-47GpJU5DpElAQzIq :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ConfigurationClassParser 解析过程
1. 处理 @PropertySource加载 .properties 配置文件并添加到 Environment
2. 处理 @ComponentScan- 扫描指定包路径- 找到 @Component/@Service/@Repository/@Controller- 递归注册为 BeanDefinition
3. 处理 @Import- 普通类 → 注册为 BeanDefinition- ImportSelector → 调用 selectImports() – AutoConfigurationImportSelector (Spring Boot)- ImportBeanDefinitionRegistrar → 延迟注册
4. 处理 @ImportResource导入 XML 配置文件
5. 处理 @Bean 方法将方法签名、依赖、initMethod/destroyMethod 等封装为 BeanMethod 对象
6. 处理父接口的 default 方法若接口有 @Bean 注解的 default 方法,同样注册
7. 递归处理内嵌的 @Configuration 类若发现新的配置类(如内部类),递归处理
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
从 BeanDefinitionRegistry 中找到所有 @Configuration 类(以及 @Component、@ComponentScan、@Import等标注的类)
创建 ConfigurationClassParser逐个解析配置类
ConfigurationClassBeanDefinitionReader将解析结果注册为 BeanDefinition- 读取收集到的 @Bean 方法 → BeanDefinition- 处理 ImportBeanDefinitionRegistrar
✅ 所有 BeanDefinition 注册完成
ConfigurationClassPostProcessor 核心源码:
// ConfigurationClassPostProcessor.java
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
// 已处理过的
} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(
beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if (configCandidates.isEmpty()) return;
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses =
new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(
bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while (!candidates.isEmpty());
}
10. 步骤 6:registerBeanPostProcessors() — 注册 Bean 后置处理器
10.1 流程图
#mermaid-svg-dKDw2cw3JU1BET7Z{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dKDw2cw3JU1BET7Z .error-icon{fill:#552222;}#mermaid-svg-dKDw2cw3JU1BET7Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dKDw2cw3JU1BET7Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dKDw2cw3JU1BET7Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dKDw2cw3JU1BET7Z .marker.cross{stroke:#333333;}#mermaid-svg-dKDw2cw3JU1BET7Z svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dKDw2cw3JU1BET7Z p{margin:0;}#mermaid-svg-dKDw2cw3JU1BET7Z .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster-label text{fill:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster-label span{color:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster-label span p{background-color:transparent;}#mermaid-svg-dKDw2cw3JU1BET7Z .label text,#mermaid-svg-dKDw2cw3JU1BET7Z span{fill:#333;color:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z .node rect,#mermaid-svg-dKDw2cw3JU1BET7Z .node circle,#mermaid-svg-dKDw2cw3JU1BET7Z .node ellipse,#mermaid-svg-dKDw2cw3JU1BET7Z .node polygon,#mermaid-svg-dKDw2cw3JU1BET7Z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dKDw2cw3JU1BET7Z .rough-node .label text,#mermaid-svg-dKDw2cw3JU1BET7Z .node .label text,#mermaid-svg-dKDw2cw3JU1BET7Z .image-shape .label,#mermaid-svg-dKDw2cw3JU1BET7Z .icon-shape .label{text-anchor:middle;}#mermaid-svg-dKDw2cw3JU1BET7Z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dKDw2cw3JU1BET7Z .rough-node .label,#mermaid-svg-dKDw2cw3JU1BET7Z .node .label,#mermaid-svg-dKDw2cw3JU1BET7Z .image-shape .label,#mermaid-svg-dKDw2cw3JU1BET7Z .icon-shape .label{text-align:center;}#mermaid-svg-dKDw2cw3JU1BET7Z .node.clickable{cursor:pointer;}#mermaid-svg-dKDw2cw3JU1BET7Z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dKDw2cw3JU1BET7Z .arrowheadPath{fill:#333333;}#mermaid-svg-dKDw2cw3JU1BET7Z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dKDw2cw3JU1BET7Z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dKDw2cw3JU1BET7Z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dKDw2cw3JU1BET7Z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dKDw2cw3JU1BET7Z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dKDw2cw3JU1BET7Z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster text{fill:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z .cluster span{color:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dKDw2cw3JU1BET7Z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dKDw2cw3JU1BET7Z rect.text{fill:none;stroke-width:0;}#mermaid-svg-dKDw2cw3JU1BET7Z .icon-shape,#mermaid-svg-dKDw2cw3JU1BET7Z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dKDw2cw3JU1BET7Z .icon-shape p,#mermaid-svg-dKDw2cw3JU1BET7Z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dKDw2cw3JU1BET7Z .icon-shape .label rect,#mermaid-svg-dKDw2cw3JU1BET7Z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dKDw2cw3JU1BET7Z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dKDw2cw3JU1BET7Z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dKDw2cw3JU1BET7Z :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
registerBeanPostProcessors(beanFactory)
从 BeanFactory 中获取所有BeanPostProcessor 类型的 Bean 名称
按优先级分类:1. 实现了 PriorityOrdered2. 实现了 Ordered3. 普通4. MergedBeanDefinitionPostProcessor
注册 PriorityOrdered 的 BPP- 排序后实例化- 注册到 BeanFactory.beanPostProcessors 列表
注册 Ordered 的 BPP- 排序后实例化- 追加到列表
注册普通的 BPP- 实例化- 追加到列表
★ 最后注册 MergedBeanDefinitionPostProcessor- 排序后实例化- 追加到列表末端
重新注册 ApplicationListenerDetector(确保它在列表末尾,在所有 BPP 之后执行)
✅ BeanPostProcessor 注册完成将在 Bean 实例化阶段被依次调用
关键细节:BeanPostProcessor 本身的实例化也在这一步完成(通过 beanFactory.getBean()),这意味着这些 Bean 会提前于普通 Bean 被实例化。
10.2 源码
// PostProcessorRegistrationDelegate.java
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory,
AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(
BeanPostProcessor.class, true, false);
int beanProcessorTargetCount =
beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(
new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors =
new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors =
new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
10.3 常见的 BeanPostProcessor
| AutowiredAnnotationBeanPostProcessor | 处理 @Autowired、@Value、@Inject 注入 |
| CommonAnnotationBeanPostProcessor | 处理 @PostConstruct、@PreDestroy、@Resource |
| ConfigurationPropertiesBindingPostProcessor | @ConfigurationProperties 属性绑定(Spring Boot) |
| ApplicationContextAwareProcessor | 处理 Aware 接口回调(步骤 3 中注册) |
| ApplicationListenerDetector | 检测 ApplicationListener Bean 并注册到多播器 |
| PersistenceExceptionTranslationPostProcessor | JPA 异常翻译 |
11. 步骤 7:initMessageSource() — 初始化消息源
// AbstractApplicationContext.java
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(
MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null &&
this.messageSource instanceof HierarchicalMessageSource hms) {
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
} else {
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}
12. 步骤 8:initApplicationEventMulticaster() — 初始化事件多播器
// AbstractApplicationContext.java
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster = beanFactory.getBean(
APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
} else {
this.applicationEventMulticaster =
new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(
APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
关键:默认的 SimpleApplicationEventMulticaster 用于同步广播事件。如需异步事件,可注册自定义的 applicationEventMulticaster Bean 并设置 TaskExecutor。
13. 步骤 9:onRefresh() — 刷新子容器
// AbstractApplicationContext.java
protected void onRefresh() throws BeansException {
// 模板方法,留给子类覆盖
}
典型覆盖场景:
| Spring Boot ServletWebServerApplicationContext | createWebServer() | 创建并启动内嵌 Tomcat/Jetty |
| Spring Boot ReactiveWebServerApplicationContext | createWebServer() | 创建并启动 Netty/Undertow |
| 普通 AbstractApplicationContext | 空实现 | 无特殊处理 |
14. 步骤 10:registerListeners() — 注册监听器
// AbstractApplicationContext.java
protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames =
getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
15. 步骤 11:finishBeanFactoryInitialization() — 完成 BeanFactory 初始化 ★★★
15.1 概述
这是另一个核心步骤,负责实例化所有非懒加载的单例 Bean。每个 Bean 在此经历完整的生命周期(实例化 → 属性填充 → 初始化 → 后置处理)。
15.2 流程图
#mermaid-svg-jqSsNJOgwpikrbJQ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jqSsNJOgwpikrbJQ .error-icon{fill:#552222;}#mermaid-svg-jqSsNJOgwpikrbJQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jqSsNJOgwpikrbJQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jqSsNJOgwpikrbJQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jqSsNJOgwpikrbJQ .marker.cross{stroke:#333333;}#mermaid-svg-jqSsNJOgwpikrbJQ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jqSsNJOgwpikrbJQ p{margin:0;}#mermaid-svg-jqSsNJOgwpikrbJQ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster-label text{fill:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster-label span{color:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster-label span p{background-color:transparent;}#mermaid-svg-jqSsNJOgwpikrbJQ .label text,#mermaid-svg-jqSsNJOgwpikrbJQ span{fill:#333;color:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ .node rect,#mermaid-svg-jqSsNJOgwpikrbJQ .node circle,#mermaid-svg-jqSsNJOgwpikrbJQ .node ellipse,#mermaid-svg-jqSsNJOgwpikrbJQ .node polygon,#mermaid-svg-jqSsNJOgwpikrbJQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jqSsNJOgwpikrbJQ .rough-node .label text,#mermaid-svg-jqSsNJOgwpikrbJQ .node .label text,#mermaid-svg-jqSsNJOgwpikrbJQ .image-shape .label,#mermaid-svg-jqSsNJOgwpikrbJQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-jqSsNJOgwpikrbJQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jqSsNJOgwpikrbJQ .rough-node .label,#mermaid-svg-jqSsNJOgwpikrbJQ .node .label,#mermaid-svg-jqSsNJOgwpikrbJQ .image-shape .label,#mermaid-svg-jqSsNJOgwpikrbJQ .icon-shape .label{text-align:center;}#mermaid-svg-jqSsNJOgwpikrbJQ .node.clickable{cursor:pointer;}#mermaid-svg-jqSsNJOgwpikrbJQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jqSsNJOgwpikrbJQ .arrowheadPath{fill:#333333;}#mermaid-svg-jqSsNJOgwpikrbJQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jqSsNJOgwpikrbJQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jqSsNJOgwpikrbJQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jqSsNJOgwpikrbJQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jqSsNJOgwpikrbJQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jqSsNJOgwpikrbJQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster text{fill:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ .cluster span{color:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jqSsNJOgwpikrbJQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jqSsNJOgwpikrbJQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-jqSsNJOgwpikrbJQ .icon-shape,#mermaid-svg-jqSsNJOgwpikrbJQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jqSsNJOgwpikrbJQ .icon-shape p,#mermaid-svg-jqSsNJOgwpikrbJQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jqSsNJOgwpikrbJQ .icon-shape .label rect,#mermaid-svg-jqSsNJOgwpikrbJQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jqSsNJOgwpikrbJQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jqSsNJOgwpikrbJQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jqSsNJOgwpikrbJQ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
DefaultListableBeanFactory.preInstantiateSingletons()
否
是
是
否
还有
遍历完成
获取所有 BeanDefinitionNames
遍历每个 BeanDefinition
非抽象 && 单例&& 非懒加载 ?
跳过此 Bean
isFactoryBean ?
getBean(FACTORY_BEAN_PREFIX + name)★ 先实例化 FactoryBean 本身(其产生的 Bean 延迟到使用时才创建)
getBean(beanName)★ ★ ★ 触发完整的 Bean 创建流程(详见图 15.3)
★ 触发所有 SmartInitializingSingleton.afterSingletonsInstantiated()典型实现:- RequestMappingHandlerAdapter (Controller 方法映射)- EventListenerMethodProcessor (@EventListener 注解处理)
finishBeanFactoryInitialization(beanFactory)
1. 初始化 ConversionService若存在名为 conversionService 的 Bean设置为 BeanFactory 的类型转换服务
2. 注册默认的嵌入式值解析器(如 ${…} 占位符解析)
3. 冻结 Configuration禁止进一步修改 BeanDefinition 元数据
4. ★ preInstantiateSingletons()预实例化所有非懒加载的单例 Bean
✅ 所有单例 Bean 已就绪BeanFactory 初始化完成
15.3 Bean 创建的完整流程(doGetBean → createBean → doCreateBean)
#mermaid-svg-TDW4p83QZpwUFAdP{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TDW4p83QZpwUFAdP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TDW4p83QZpwUFAdP .error-icon{fill:#552222;}#mermaid-svg-TDW4p83QZpwUFAdP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TDW4p83QZpwUFAdP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TDW4p83QZpwUFAdP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TDW4p83QZpwUFAdP .marker.cross{stroke:#333333;}#mermaid-svg-TDW4p83QZpwUFAdP svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TDW4p83QZpwUFAdP p{margin:0;}#mermaid-svg-TDW4p83QZpwUFAdP .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-TDW4p83QZpwUFAdP .cluster-label text{fill:#333;}#mermaid-svg-TDW4p83QZpwUFAdP .cluster-label span{color:#333;}#mermaid-svg-TDW4p83QZpwUFAdP .cluster-label span p{background-color:transparent;}#mermaid-svg-TDW4p83QZpwUFAdP .label text,#mermaid-svg-TDW4p83QZpwUFAdP span{fill:#333;color:#333;}#mermaid-svg-TDW4p83QZpwUFAdP .node rect,#mermaid-svg-TDW4p83QZpwUFAdP .node circle,#mermaid-svg-TDW4p83QZpwUFAdP .node ellipse,#mermaid-svg-TDW4p83QZpwUFAdP .node polygon,#mermaid-svg-TDW4p83QZpwUFAdP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TDW4p83QZpwUFAdP .rough-node .label text,#mermaid-svg-TDW4p83QZpwUFAdP .node .label text,#mermaid-svg-TDW4p83QZpwUFAdP .image-shape .label,#mermaid-svg-TDW4p83QZpwUFAdP .icon-shape .label{text-anchor:middle;}#mermaid-svg-TDW4p83QZpwUFAdP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TDW4p83QZpwUFAdP .rough-node .label,#mermaid-svg-TDW4p83QZpwUFAdP .node .label,#mermaid-svg-TDW4p83QZpwUFAdP .image-shape .label,#mermaid-svg-TDW4p83QZpwUFAdP .icon-shape .label{text-align:center;}#mermaid-svg-TDW4p83QZpwUFAdP .node.clickable{cursor:pointer;}#mermaid-svg-TDW4p83QZpwUFAdP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TDW4p83QZpwUFAdP .arrowheadPath{fill:#333333;}#mermaid-svg-TDW4p83QZpwUFAdP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TDW4p83QZpwUFAdP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TDW4p83QZpwUFAdP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TDW4p83QZpwUFAdP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TDW4p83QZpwUFAdP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TDW4p83QZpwUFAdP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TDW4p83QZpwUFAdP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TDW4p83QZpwUFAdP .cluster text{fill:#333;}#mermaid-svg-TDW4p83QZpwUFAdP .cluster span{color:#333;}#mermaid-svg-TDW4p83QZpwUFAdP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TDW4p83QZpwUFAdP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TDW4p83QZpwUFAdP rect.text{fill:none;stroke-width:0;}#mermaid-svg-TDW4p83QZpwUFAdP .icon-shape,#mermaid-svg-TDW4p83QZpwUFAdP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TDW4p83QZpwUFAdP .icon-shape p,#mermaid-svg-TDW4p83QZpwUFAdP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TDW4p83QZpwUFAdP .icon-shape .label rect,#mermaid-svg-TDW4p83QZpwUFAdP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TDW4p83QZpwUFAdP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TDW4p83QZpwUFAdP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TDW4p83QZpwUFAdP :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
缓存命中
缓存未命中
存在
不存在
singleton
prototype
request/session/…
doCreateBean() — 核心创建过程
initializeBean() 详细过程
invokeAwareMethods()调用 Aware 接口方法:- BeanNameAware.setBeanName()- BeanClassLoaderAware.setBeanClassLoader()- BeanFactoryAware.setBeanFactory()
★ applyBeanPostProcessorsBeforeInitialization()遍历所有 BeanPostProcessor调用 postProcessBeforeInitialization()典型实现: @PostConstruct 注解处理(CommonAnnotationBeanPostProcessor)
invokeInitMethods()★ 调用初始化方法- 若实现了 InitializingBean → afterPropertiesSet()- 若配置了 initMethod → 反射调用
★ applyBeanPostProcessorsAfterInitialization()遍历所有 BeanPostProcessor调用 postProcessAfterInitialization()典型实现: AOP 代理创建(AbstractAutoProxyCreator)
① createBeanInstance()★ 实例化 Bean(创建对象)- 若有 Supplier → Supplier.get()- 若有工厂方法 → 通过工厂方法创建- 确定构造器 → 反射调用构造器 – 若只有一个构造器 → 直接使用 – 若有多个构造器 → SmartInstantiationAwareBeanPostProcessor .determineConstructorsFromBeanPostProcessors() 选出 @Autowired 标注的构造器 – CGLIB 子类化场景 → 使用 objenesis 创建
② applyMergedBeanDefinitionPostProcessors()★ 后置处理合并后的 BeanDefinition(如 AutowiredAnnotationBeanPostProcessor 收集 @Autowired 注入点元数据)
③ ★ addSingletonFactory()将 Bean 的早期引用放入三级缓存(用于解决循环依赖)singletonFactories.put(beanName, () → getEarlyBeanReference(beanName, mbd, bean))
④ ★ populateBean()属性填充 / 依赖注入
populateBean() 详细过程
遍历 InstantiationAwareBeanPostProcessor调用 postProcessAfterInstantiation()可在此终止属性填充
★ 解析自动装配模式(AUTOWIRE_BY_NAME / AUTOWIRE_BY_TYPE)如果不是显式指定的,跳过
★ 遍历 InstantiationAwareBeanPostProcessor调用 postProcessProperties()AutowiredAnnotationBeanPostProcessor: 收集 @Autowired/@Value 注入点 并实际执行依赖注入CommonAnnotationBeanPostProcessor: 收集 @Resource 注入点 并实际执行依赖注入
进行实际的属性填充(通过反射执行依赖注入)
⑤ ★ initializeBean()Bean 初始化
⑥ ★ 循环依赖检查若 Bean 在创建过程中被其他线程从缓存中获取,确保是最终版本
getBean(name)
doGetBean(name, type, args, typeCheckOnly)
★ getSingleton(beanName)从三级缓存中获取(一级: singletonObjects 二级: earlySingletonObjects 三级: singletonFactories)
直接返回
父容器中存在?(双亲委派)
从父容器获取并返回
getMergedLocalBeanDefinition(beanName)合并 BeanDefinition(父子 BeanDefinition 合并)
检查 depends-on 依赖先实例化 depends-on 指定的 Bean
Scope ?
★ createBean(beanName, mbd, args)→ doCreateBean()
prototype 创建每次请求都创建新实例
调用对应 Scope 的 get() 方法
addSingleton(beanName, singletonObject)★ 将最终成品 Bean 放入一级缓存singletonObjects.put(beanName, singletonObject)同时从二三级缓存中移除
✅ 返回完整的 Bean 实例
15.4 源码关键片段
getBean 入口:
// AbstractBeanFactory.java
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType,
@Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = transformedBeanName(name);
// ★ 第一步:尝试从缓存中获取(三级缓存解决循环依赖)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 委托父容器
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);
getBean(dep); // 递归创建依赖的 Bean
}
}
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope scope = this.scopes.get(scopeName);
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
// 类型转换
}
return (T) bean;
}
15.5 三级缓存解决循环依赖
// DefaultSingletonBeanRegistry.java
/** 一级缓存:完全初始化完成的 Bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存:早期暴露的 Bean(未完成属性填充和初始化) */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** 三级缓存:Bean 工厂(用于生成早期 Bean 引用,支持 AOP 代理) */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 正在创建中的 Bean 集合(用于循环依赖检测) */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory =
this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
循环依赖解决流程:
#mermaid-svg-yy0f15QLySJBlI1j{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yy0f15QLySJBlI1j .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yy0f15QLySJBlI1j .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yy0f15QLySJBlI1j .error-icon{fill:#552222;}#mermaid-svg-yy0f15QLySJBlI1j .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yy0f15QLySJBlI1j .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yy0f15QLySJBlI1j .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yy0f15QLySJBlI1j .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yy0f15QLySJBlI1j .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yy0f15QLySJBlI1j .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yy0f15QLySJBlI1j .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yy0f15QLySJBlI1j .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yy0f15QLySJBlI1j .marker.cross{stroke:#333333;}#mermaid-svg-yy0f15QLySJBlI1j svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yy0f15QLySJBlI1j p{margin:0;}#mermaid-svg-yy0f15QLySJBlI1j .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-yy0f15QLySJBlI1j .cluster-label text{fill:#333;}#mermaid-svg-yy0f15QLySJBlI1j .cluster-label span{color:#333;}#mermaid-svg-yy0f15QLySJBlI1j .cluster-label span p{background-color:transparent;}#mermaid-svg-yy0f15QLySJBlI1j .label text,#mermaid-svg-yy0f15QLySJBlI1j span{fill:#333;color:#333;}#mermaid-svg-yy0f15QLySJBlI1j .node rect,#mermaid-svg-yy0f15QLySJBlI1j .node circle,#mermaid-svg-yy0f15QLySJBlI1j .node ellipse,#mermaid-svg-yy0f15QLySJBlI1j .node polygon,#mermaid-svg-yy0f15QLySJBlI1j .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yy0f15QLySJBlI1j .rough-node .label text,#mermaid-svg-yy0f15QLySJBlI1j .node .label text,#mermaid-svg-yy0f15QLySJBlI1j .image-shape .label,#mermaid-svg-yy0f15QLySJBlI1j .icon-shape .label{text-anchor:middle;}#mermaid-svg-yy0f15QLySJBlI1j .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yy0f15QLySJBlI1j .rough-node .label,#mermaid-svg-yy0f15QLySJBlI1j .node .label,#mermaid-svg-yy0f15QLySJBlI1j .image-shape .label,#mermaid-svg-yy0f15QLySJBlI1j .icon-shape .label{text-align:center;}#mermaid-svg-yy0f15QLySJBlI1j .node.clickable{cursor:pointer;}#mermaid-svg-yy0f15QLySJBlI1j .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yy0f15QLySJBlI1j .arrowheadPath{fill:#333333;}#mermaid-svg-yy0f15QLySJBlI1j .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yy0f15QLySJBlI1j .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yy0f15QLySJBlI1j .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yy0f15QLySJBlI1j .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yy0f15QLySJBlI1j .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yy0f15QLySJBlI1j .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yy0f15QLySJBlI1j .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yy0f15QLySJBlI1j .cluster text{fill:#333;}#mermaid-svg-yy0f15QLySJBlI1j .cluster span{color:#333;}#mermaid-svg-yy0f15QLySJBlI1j div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yy0f15QLySJBlI1j .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yy0f15QLySJBlI1j rect.text{fill:none;stroke-width:0;}#mermaid-svg-yy0f15QLySJBlI1j .icon-shape,#mermaid-svg-yy0f15QLySJBlI1j .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yy0f15QLySJBlI1j .icon-shape p,#mermaid-svg-yy0f15QLySJBlI1j .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yy0f15QLySJBlI1j .icon-shape .label rect,#mermaid-svg-yy0f15QLySJBlI1j .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yy0f15QLySJBlI1j .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yy0f15QLySJBlI1j .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yy0f15QLySJBlI1j :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
经典循环依赖场景: A → B → A
创建 A 实例 ✓
A 的早期引用放入三级缓存 ✓
A 需要注入 B
触发 B 的创建
创建 B 实例 ✓
B 需要注入 A
★ 从三级缓存获取 A 的早期引用 ✓
B 完成属性填充
B 完成初始化
B 完成 → 放入一级缓存
A 获得完整的 B 实例
A 完成属性填充
A 完成初始化 → 放入一级缓存
注意:Spring 只支持单例 Bean 的 Setter/Field 注入循环依赖。构造器注入的循环依赖无法解决。Spring Boot 3 默认禁用循环依赖(setAllowCircularReferences(false))。
16. 步骤 12:finishRefresh() — 完成刷新
16.1 源码
// AbstractApplicationContext.java
protected void finishRefresh() {
// 1. 清除上下文级 Resource 缓存
clearResourceCaches();
// 2. 初始化生命周期处理器
initLifecycleProcessor();
// 3. ★ 启动所有实现了 Lifecycle 接口的 Bean
getLifecycleProcessor().onRefresh();
// 4. ★ 发布 ContextRefreshedEvent(标志着容器已完全就绪)
publishEvent(new ContextRefreshedEvent(this));
// 5. 向 LiveBeansView 注册(JMX 支持)
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
16.2 LifecycleProcessor
// AbstractApplicationContext.java
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(
LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
DefaultLifecycleProcessor.onRefresh() 会找到所有实现了 Lifecycle 接口的 Bean,按 phase 排序后调用 start() 方法。
17. Bean 的完整生命周期
17.1 生命周期全景图
#mermaid-svg-FyMrHWDCChjXoTo9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FyMrHWDCChjXoTo9 .error-icon{fill:#552222;}#mermaid-svg-FyMrHWDCChjXoTo9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FyMrHWDCChjXoTo9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FyMrHWDCChjXoTo9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FyMrHWDCChjXoTo9 .marker.cross{stroke:#333333;}#mermaid-svg-FyMrHWDCChjXoTo9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FyMrHWDCChjXoTo9 p{margin:0;}#mermaid-svg-FyMrHWDCChjXoTo9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster-label text{fill:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster-label span{color:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster-label span p{background-color:transparent;}#mermaid-svg-FyMrHWDCChjXoTo9 .label text,#mermaid-svg-FyMrHWDCChjXoTo9 span{fill:#333;color:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 .node rect,#mermaid-svg-FyMrHWDCChjXoTo9 .node circle,#mermaid-svg-FyMrHWDCChjXoTo9 .node ellipse,#mermaid-svg-FyMrHWDCChjXoTo9 .node polygon,#mermaid-svg-FyMrHWDCChjXoTo9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FyMrHWDCChjXoTo9 .rough-node .label text,#mermaid-svg-FyMrHWDCChjXoTo9 .node .label text,#mermaid-svg-FyMrHWDCChjXoTo9 .image-shape .label,#mermaid-svg-FyMrHWDCChjXoTo9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-FyMrHWDCChjXoTo9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FyMrHWDCChjXoTo9 .rough-node .label,#mermaid-svg-FyMrHWDCChjXoTo9 .node .label,#mermaid-svg-FyMrHWDCChjXoTo9 .image-shape .label,#mermaid-svg-FyMrHWDCChjXoTo9 .icon-shape .label{text-align:center;}#mermaid-svg-FyMrHWDCChjXoTo9 .node.clickable{cursor:pointer;}#mermaid-svg-FyMrHWDCChjXoTo9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FyMrHWDCChjXoTo9 .arrowheadPath{fill:#333333;}#mermaid-svg-FyMrHWDCChjXoTo9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FyMrHWDCChjXoTo9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FyMrHWDCChjXoTo9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FyMrHWDCChjXoTo9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FyMrHWDCChjXoTo9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FyMrHWDCChjXoTo9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster text{fill:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 .cluster span{color:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FyMrHWDCChjXoTo9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FyMrHWDCChjXoTo9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-FyMrHWDCChjXoTo9 .icon-shape,#mermaid-svg-FyMrHWDCChjXoTo9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FyMrHWDCChjXoTo9 .icon-shape p,#mermaid-svg-FyMrHWDCChjXoTo9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FyMrHWDCChjXoTo9 .icon-shape .label rect,#mermaid-svg-FyMrHWDCChjXoTo9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FyMrHWDCChjXoTo9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FyMrHWDCChjXoTo9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FyMrHWDCChjXoTo9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
销毁阶段
就绪阶段
初始化阶段
属性填充阶段
后置处理阶段
实例化阶段
BeanDefinition 阶段
1. BeanDefinition 注册(XML 解析 / 注解扫描 / @Bean 方法)
2. BeanDefinition 合并(getMergedLocalBeanDefinition)合并父 BeanDefinition 的属性
3. 构造器推断SmartInstantiationAwareBeanPostProcessor.determineConstructorsFromBeanPostProcessors()
4. ★ 实例化反射调用构造器 / CGLIB 子类化(objenesis)createBeanInstance()
5. MergedBeanDefinition 后置处理applyMergedBeanDefinitionPostProcessors()(收集 @Autowired/@Value 元数据)
6. ★ 三级缓存暴露addSingletonFactory()(允许循环依赖的其他 Bean 引用此早期对象)
7. ★ InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()可在此决定是否继续填充
8. ★ 依赖注入InstantiationAwareBeanPostProcessor.postProcessProperties()- @Autowired / @Value- @Resource
9. Aware 接口回调- BeanNameAware- BeanClassLoaderAware- BeanFactoryAware- ApplicationContextAware (由 BPP 处理)
10. ★ BPP.postProcessBeforeInitialization()- @PostConstruct (CommonAnnotationBeanPostProcessor)
11. InitializingBean.afterPropertiesSet()
12. 自定义 init-method
13. ★ BPP.postProcessAfterInitialization()- AOP 代理创建 (AbstractAutoProxyCreator)
14. ★ Bean 就绪放入一级缓存 singletonObjects
15. SmartInitializingSingleton.afterSingletonsInstantiated()
16. DisposableBean.destroy()
17. 自定义 destroy-method
18. @PreDestroy 方法
17.2 生命周期中的关键接口
| BeanNameAware | 感知自身 Bean 名称 | 初始化前 |
| BeanClassLoaderAware | 感知类加载器 | 初始化前 |
| BeanFactoryAware | 感知所属 BeanFactory | 初始化前 |
| ApplicationContextAware | 感知所属 ApplicationContext | 初始化前 |
| @PostConstruct | 初始化回调(JSR-250) | 初始化 |
| InitializingBean.afterPropertiesSet() | 初始化回调(Spring 原生) | 初始化 |
| init-method | 自定义初始化方法 | 初始化 |
| BeanPostProcessor | 所有 Bean 的前/后置处理 | 全局 |
| InstantiationAwareBeanPostProcessor | 实例化前后的处理 | 实例化+填充 |
| SmartInstantiationAwareBeanPostProcessor | 构造器推断、早期引用等 | 实例化 |
| SmartInitializingSingleton | 所有单例 Bean 就绪后的回调 | 就绪 |
| @PreDestroy | 销毁回调(JSR-250) | 销毁 |
| DisposableBean.destroy() | 销毁回调(Spring 原生) | 销毁 |
| destroy-method | 自定义销毁方法 | 销毁 |
18. 核心类继承关系
#mermaid-svg-8r50gBq6BwvA4jij{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8r50gBq6BwvA4jij .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8r50gBq6BwvA4jij .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8r50gBq6BwvA4jij .error-icon{fill:#552222;}#mermaid-svg-8r50gBq6BwvA4jij .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8r50gBq6BwvA4jij .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8r50gBq6BwvA4jij .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8r50gBq6BwvA4jij .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8r50gBq6BwvA4jij .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8r50gBq6BwvA4jij .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8r50gBq6BwvA4jij .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8r50gBq6BwvA4jij .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8r50gBq6BwvA4jij .marker.cross{stroke:#333333;}#mermaid-svg-8r50gBq6BwvA4jij svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8r50gBq6BwvA4jij p{margin:0;}#mermaid-svg-8r50gBq6BwvA4jij g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-8r50gBq6BwvA4jij g.classGroup text .title{font-weight:bolder;}#mermaid-svg-8r50gBq6BwvA4jij .cluster-label text{fill:#333;}#mermaid-svg-8r50gBq6BwvA4jij .cluster-label span{color:#333;}#mermaid-svg-8r50gBq6BwvA4jij .cluster-label span p{background-color:transparent;}#mermaid-svg-8r50gBq6BwvA4jij .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8r50gBq6BwvA4jij .cluster text{fill:#333;}#mermaid-svg-8r50gBq6BwvA4jij .cluster span{color:#333;}#mermaid-svg-8r50gBq6BwvA4jij .nodeLabel,#mermaid-svg-8r50gBq6BwvA4jij .edgeLabel{color:#131300;}#mermaid-svg-8r50gBq6BwvA4jij .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-8r50gBq6BwvA4jij .label text{fill:#131300;}#mermaid-svg-8r50gBq6BwvA4jij .labelBkg{background:#ECECFF;}#mermaid-svg-8r50gBq6BwvA4jij .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-8r50gBq6BwvA4jij .classTitle{font-weight:bolder;}#mermaid-svg-8r50gBq6BwvA4jij .node rect,#mermaid-svg-8r50gBq6BwvA4jij .node circle,#mermaid-svg-8r50gBq6BwvA4jij .node ellipse,#mermaid-svg-8r50gBq6BwvA4jij .node polygon,#mermaid-svg-8r50gBq6BwvA4jij .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8r50gBq6BwvA4jij .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij g.clickable{cursor:pointer;}#mermaid-svg-8r50gBq6BwvA4jij g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-8r50gBq6BwvA4jij g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-8r50gBq6BwvA4jij .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-8r50gBq6BwvA4jij .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-8r50gBq6BwvA4jij .dashed-line{stroke-dasharray:3;}#mermaid-svg-8r50gBq6BwvA4jij .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-8r50gBq6BwvA4jij #compositionStart,#mermaid-svg-8r50gBq6BwvA4jij .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #compositionEnd,#mermaid-svg-8r50gBq6BwvA4jij .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #dependencyStart,#mermaid-svg-8r50gBq6BwvA4jij .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #dependencyStart,#mermaid-svg-8r50gBq6BwvA4jij .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #extensionStart,#mermaid-svg-8r50gBq6BwvA4jij .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #extensionEnd,#mermaid-svg-8r50gBq6BwvA4jij .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #aggregationStart,#mermaid-svg-8r50gBq6BwvA4jij .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #aggregationEnd,#mermaid-svg-8r50gBq6BwvA4jij .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #lollipopStart,#mermaid-svg-8r50gBq6BwvA4jij .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij #lollipopEnd,#mermaid-svg-8r50gBq6BwvA4jij .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-8r50gBq6BwvA4jij .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-8r50gBq6BwvA4jij .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8r50gBq6BwvA4jij .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8r50gBq6BwvA4jij .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8r50gBq6BwvA4jij :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
uses
contains
«interface»
ConfigurableApplicationContext
+refresh()
+close()
+getBeanFactory() : ConfigurableListableBeanFactory
AbstractApplicationContext
-ConfigurableEnvironment environment
-ApplicationEventMulticaster applicationEventMulticaster
+refresh()
#prepareRefresh()
#obtainFreshBeanFactory() : ConfigurableListableBeanFactory
#prepareBeanFactory(beanFactory)
#invokeBeanFactoryPostProcessors(beanFactory)
#registerBeanPostProcessors(beanFactory)
#onRefresh()
#finishBeanFactoryInitialization(beanFactory)
#finishRefresh()
GenericApplicationContext
-DefaultListableBeanFactory beanFactory
+getBeanFactory()
AnnotationConfigApplicationContext
-AnnotatedBeanDefinitionReader reader
-ClassPathBeanDefinitionScanner scanner
+register()
+scan()
«interface»
ConfigurableListableBeanFactory
+preInstantiateSingletons()
+getBeanDefinitionNames()
DefaultListableBeanFactory
-Map<String, BeanDefinition> beanDefinitionMap
-Map<String, Object> singletonObjects
+registerBeanDefinition()
+getBean()
AbstractAutowireCapableBeanFactory
+createBean()
+doCreateBean()
+populateBean()
+initializeBean()
AbstractBeanFactory
+getBean()
+doGetBean()
+getMergedLocalBeanDefinition()
19. 关键扩展点总结
19.1 扩展点一览
#mermaid-svg-3TxgwLl9okaZf3Rp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3TxgwLl9okaZf3Rp .error-icon{fill:#552222;}#mermaid-svg-3TxgwLl9okaZf3Rp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3TxgwLl9okaZf3Rp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3TxgwLl9okaZf3Rp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3TxgwLl9okaZf3Rp .marker.cross{stroke:#333333;}#mermaid-svg-3TxgwLl9okaZf3Rp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3TxgwLl9okaZf3Rp p{margin:0;}#mermaid-svg-3TxgwLl9okaZf3Rp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster-label text{fill:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster-label span{color:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster-label span p{background-color:transparent;}#mermaid-svg-3TxgwLl9okaZf3Rp .label text,#mermaid-svg-3TxgwLl9okaZf3Rp span{fill:#333;color:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp .node rect,#mermaid-svg-3TxgwLl9okaZf3Rp .node circle,#mermaid-svg-3TxgwLl9okaZf3Rp .node ellipse,#mermaid-svg-3TxgwLl9okaZf3Rp .node polygon,#mermaid-svg-3TxgwLl9okaZf3Rp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3TxgwLl9okaZf3Rp .rough-node .label text,#mermaid-svg-3TxgwLl9okaZf3Rp .node .label text,#mermaid-svg-3TxgwLl9okaZf3Rp .image-shape .label,#mermaid-svg-3TxgwLl9okaZf3Rp .icon-shape .label{text-anchor:middle;}#mermaid-svg-3TxgwLl9okaZf3Rp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3TxgwLl9okaZf3Rp .rough-node .label,#mermaid-svg-3TxgwLl9okaZf3Rp .node .label,#mermaid-svg-3TxgwLl9okaZf3Rp .image-shape .label,#mermaid-svg-3TxgwLl9okaZf3Rp .icon-shape .label{text-align:center;}#mermaid-svg-3TxgwLl9okaZf3Rp .node.clickable{cursor:pointer;}#mermaid-svg-3TxgwLl9okaZf3Rp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3TxgwLl9okaZf3Rp .arrowheadPath{fill:#333333;}#mermaid-svg-3TxgwLl9okaZf3Rp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3TxgwLl9okaZf3Rp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3TxgwLl9okaZf3Rp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3TxgwLl9okaZf3Rp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3TxgwLl9okaZf3Rp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3TxgwLl9okaZf3Rp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster text{fill:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp .cluster span{color:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3TxgwLl9okaZf3Rp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3TxgwLl9okaZf3Rp rect.text{fill:none;stroke-width:0;}#mermaid-svg-3TxgwLl9okaZf3Rp .icon-shape,#mermaid-svg-3TxgwLl9okaZf3Rp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3TxgwLl9okaZf3Rp .icon-shape p,#mermaid-svg-3TxgwLl9okaZf3Rp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3TxgwLl9okaZf3Rp .icon-shape .label rect,#mermaid-svg-3TxgwLl9okaZf3Rp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3TxgwLl9okaZf3Rp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3TxgwLl9okaZf3Rp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3TxgwLl9okaZf3Rp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Bean 级扩展 (在 Bean 生命周期中)
@PostConstruct / InitializingBean→ Bean 初始化回调
@PreDestroy / DisposableBean→ Bean 销毁回调
SmartInitializingSingleton→ 所有单例 Bean 就绪后回调
Lifecycle / SmartLifecycle→ 容器启动/停止时的生命周期回调
FactoryBean→ 自定义 Bean 的创建逻辑
容器级扩展 (在 refresh 各步骤中)
BeanFactoryPostProcessor(包括 BeanDefinitionRegistryPostProcessor)→ 修改 BeanDefinition→ 步骤5 执行
BeanPostProcessor→ 拦截 Bean 实例化过程→ 步骤6 注册,步骤11 调用
Aware 接口→ Bean 感知容器资源→ 步骤3 注册处理器,步骤11 调用
ApplicationListener→ 容器事件监听→ 步骤10 注册
19.2 容器级扩展点总结
| 步骤 1 | initPropertySources() | prepareRefresh() 中 | 初始化自定义属性源 |
| 步骤 4 | postProcessBeanFactory() | BeanFactory 准备后 | 注册特殊 scope、BPP 等 |
| 步骤 5 | BeanFactoryPostProcessor | 所有 BeanDefinition 注册后 | 修改 BeanDefinition |
| 步骤 5 | BeanDefinitionRegistryPostProcessor | 同上,但更早 | 注册额外的 BeanDefinition |
| 步骤 6 | BeanPostProcessor | Bean 实例化前后 | 拦截 Bean 创建过程 |
| 步骤 9 | onRefresh() | finishBeanFactoryInitialization 之前 | Spring Boot 在此启动 WebServer |
| 步骤 11 | SmartInitializingSingleton | 所有单例 Bean 就绪后 | 容器完全就绪后的回调 |
| 步骤 12 | LifecycleProcessor | finishRefresh() 中 | 启动/停止 Lifecycle Bean |
总结
| IoC 思想 | 控制反转——对象不再自己控制依赖,由容器统一管理 |
| DI 实现 | 构造器注入(推荐)、Setter 注入、字段注入 |
| Bean 元数据 | BeanDefinition 是 Bean 的"配方",包含创建所需的所有信息 |
| Bean 作用域 | singleton(默认)、prototype、request、session、application、websocket |
| 循环依赖 | Spring 通过三级缓存解决 Setter/Field 注入的循环依赖 |
| FactoryBean | 使用 &beanName 获取 FactoryBean 自身,beanName 获取产物 |
Spring IoC 容器的启动过程 = 12 步 refresh():
| 步骤 5 | invokeBeanFactoryPostProcessors() | ConfigurationClassPostProcessor 解析配置类,扫描组件,注册所有 BeanDefinition |
| 步骤 6 | registerBeanPostProcessors() | 注册 BeanPostProcessor,这些拦截器将在每个 Bean 创建时被调用 |
| 步骤 11 | finishBeanFactoryInitialization() | 实例化所有单例 Bean:实例化 → 属性填充 → 初始化 → AOP 代理 |
一条完整的调用链:
getBean() → doGetBean() → getSingleton()(查缓存)
→ createBean() → doCreateBean()
→ createBeanInstance()(实例化)
→ populateBean()(注入)
→ initializeBean()(初始化 + AOP)
→ addSingleton()(放入缓存)
理解这些,就掌握了 Spring IoC 容器的核心精髓。
2026年8月12日,成都,各位看官老爷,欲知后事如何且听下回分解





