Spring 创建 Bean 实例的过程主要由 BeanFactory 接口及其实现类(通常是 AbstractBeanFactory 的 doGetBean 方法和 DefaultListableBeanFactory 的 preInstantiateSingletons 方法)负责。这个过程涉及多个步骤,包括 Bean 定义的解析、依赖的处理、实例化、属性填充、初始化等。
以下是 Spring 创建 Bean 实例的详细步骤:
1. 获取 Bean 定义 (Get BeanDefinition):
- 从 
BeanDefinitionRegistry(通常是DefaultListableBeanFactory内部的Map) 中根据 Bean 的名称获取对应的BeanDefinition对象。 
2. 检查是否已创建 (Check if already created):
- 单例 Bean (Singleton): 检查该 Bean 是否已经创建并缓存(在 
singletonObjects一级缓存中)。如果是,直接返回缓存的实例。 - 原型 Bean (Prototype): 每次请求都会创建新的实例。
 - 其他作用域 (Request, Session, etc.): 根据具体的作用域规则进行检查。
 
3. 处理 depends-on (Handle depends-on):
- 如果该 Bean 定义了 
depends-on属性(依赖于其他 Bean),则先递归地创建并初始化它所依赖的 Bean。 
4. 创建 Bean 实例 (Create Bean Instance):
-  
选择创建方式: Spring 支持多种创建 Bean 实例的方式:
- 构造函数 (Constructor): 使用 Bean 类的构造函数创建实例(最常见的方式)。 
- 无参构造函数: 如果没有指定构造函数参数,则使用无参构造函数。
 - 有参构造函数: 如果指定了构造函数参数,则使用匹配的构造函数。 
- 自动装配构造函数参数: 根据类型或名称自动解析构造函数参数。
 - 手动指定构造函数参数: 在 XML 配置或 Java 配置中显式指定构造函数参数。
 
 
 - 静态工厂方法 (Static Factory Method): 使用静态工厂方法创建实例。 
- 在 Bean 定义中指定 
factory-method属性,指向静态工厂方法。 - 静态工厂方法必须返回 Bean 的实例。
 
 - 在 Bean 定义中指定 
 - 实例工厂方法 (Instance Factory Method): 使用实例工厂方法创建实例。 
- 在 Bean 定义中指定 
factory-bean属性,指向工厂 Bean。 - 在 Bean 定义中指定 
factory-method属性,指向工厂 Bean 中的实例方法。 - 实例工厂方法必须返回 Bean 的实例。
 
 - 在 Bean 定义中指定 
 FactoryBean: 如果 Bean 本身是一个FactoryBean,则调用其getObject()方法来获取实际的 Bean 实例。FactoryBean是一个特殊的 Bean,它可以创建和返回其他 Bean 的实例。
 - 构造函数 (Constructor): 使用 Bean 类的构造函数创建实例(最常见的方式)。 
 -  
实例化:
- 反射 (Reflection): 通常情况下,Spring 使用 Java 反射机制(
Constructor.newInstance()或Method.invoke())调用构造函数或工厂方法来创建 Bean 实例。 - CGLIB: 如果需要创建代理对象,Spring 可能会使用 CGLIB 动态生成子类。
 InstantiationAwareBeanPostProcessor: 在 Bean 实例化前后,Spring 会调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation和postProcessAfterInstantiation方法,允许对实例化过程进行干预(例如,返回一个代理对象而不是原始的 Bean 实例)。
 - 反射 (Reflection): 通常情况下,Spring 使用 Java 反射机制(
 
5. 循环依赖处理 (早期暴露):
- 如果是单例 Bean 且允许循环依赖, 则在实例化之后, 属性注入之前, 将创建 Bean 的 ObjectFactory 放入三级缓存 (singletonFactories), 以便其他 Bean 在创建过程中可以获取到该 Bean 的早期引用.
 
6. 属性填充 (Populate Bean):
- 将 Bean 定义中指定的属性值设置到 Bean 实例中。
 - 注入方式: 
- Setter 注入: 调用 Bean 的 Setter 方法。
 - 字段注入: 直接设置 Bean 的字段值(不推荐)。
 
 - 属性解析: 
- 字面量值: 直接设置字符串、数字、布尔值等字面量值。
 - 引用其他 Bean: 根据 Bean 的名称或类型,从容器中获取依赖的 Bean,并注入。 
- 自动装配 (Autowiring): 根据类型 (byType)、名称 (byName) 或构造函数 (constructor) 自动解析和注入依赖。
 - 手动装配: 在 XML 配置或 Java 配置中显式指定依赖关系。
 @Autowired、@Resource、@Value等注解: 由AutowiredAnnotationBeanPostProcessor(实现了InstantiationAwareBeanPostProcessor) 处理。
 - 集合、数组、Map: 解析配置中的集合、数组、Map 元素,并注入。
 - SpEL 表达式: 解析 SpEL 表达式,并将结果注入。
 - 占位符: 解析占位符(例如,
${property.name}),并从属性源(PropertySource)中获取值。 
 - 类型转换: 如果属性的类型与配置值的类型不匹配,Spring 会尝试进行类型转换(使用 
TypeConverter、ConversionService或自定义的PropertyEditor)。 InstantiationAwareBeanPostProcessor.postProcessProperties/postProcessPropertyValues:- 在属性注入阶段, 会调用 
InstantiationAwareBeanPostProcessor的postProcessProperties(或postProcessPropertyValues, 已弃用) 方法. - 允许对属性值进行修改或执行其他操作.
 
- 在属性注入阶段, 会调用 
 
7. Aware 接口回调:
- 如果 Bean 实现了 Spring 提供的一些 Aware 接口,容器会在属性注入完成后、初始化之前调用这些接口的方法,将相应的资源注入到 Bean 中。
 - 常见的 Aware 接口: 
BeanNameAware: 注入 Bean 的名称。BeanFactoryAware: 注入BeanFactory。ApplicationContextAware: 注入ApplicationContext。EnvironmentAware: 注入Environment。ResourceLoaderAware: 注入ResourceLoader。MessageSourceAware: 注入MessageSource。- 其他…
 
 
8. 初始化 (Initialization):
-  
BeanPostProcessor前置处理:- 调用所有已注册的 
BeanPostProcessor的postProcessBeforeInitialization方法。 - 允许在 Bean 初始化之前对 Bean 进行修改或执行其他操作(例如,AOP 代理就是在这里创建的)。
 
 - 调用所有已注册的 
 -  
调用初始化方法:
InitializingBean接口: 如果 Bean 实现了InitializingBean接口,则调用其afterPropertiesSet方法。@PostConstruct注解: 如果 Bean 的方法上有@PostConstruct注解,则调用该方法。init-method属性: 如果 Bean 定义中指定了init-method属性,则调用指定的方法(通过反射)。
 -  
BeanPostProcessor后置处理:- 调用所有已注册的 
BeanPostProcessor的postProcessAfterInitialization方法。 - 允许在 Bean 初始化之后对 Bean 进行修改或执行其他操作。
 
 - 调用所有已注册的 
 
9. 注册一次性 Bean (Register Disposable Bean):
- 如果 Bean 实现了 
DisposableBean接口,或者定义了销毁方法(@PreDestroy注解或destroy-method属性),则将该 Bean 注册为一次性 Bean,以便在容器关闭时销毁。 
10. 完成 (Completion):
- 对于单例 Bean,将创建好的 Bean 实例放入单例缓存中(
singletonObjects一级缓存)。 - 对于原型 Bean,将创建好的 Bean 实例返回给调用者。
 
总结流程图:
+-----------------------+
|    getBean(name)     |  (获取 Bean)
+-----------------------+|V
+-----------------------+
|  Get BeanDefinition   |  (获取 Bean 定义)
+-----------------------+|V
+-----------------------+
| Check if created      |  (检查是否已创建)
+-----------------------+|V
+-----------------------+
| Handle depends-on     |  (处理 depends-on)
+-----------------------+|V
+-----------------------+
| Create Bean Instance  |  (创建 Bean 实例)
+-----------------------+||  - 选择创建方式:|    - 构造函数 (无参/有参, 自动装配/手动指定)|    - 静态工厂方法|    - 实例工厂方法|    - FactoryBean|  - 实例化:|    - 反射 (Constructor.newInstance() 或 Method.invoke())|    - CGLIB (如果需要创建代理)|  - InstantiationAwareBeanPostProcessor (before/after)|V
+---------------------------+
| Early Singleton Exposure  | (早期暴露, 处理循环依赖)
+---------------------------+|V
+-----------------------+
|   Populate Bean       |  (属性填充)
+-----------------------+||  - 注入方式:|    - Setter 注入|    - 字段注入|  - 属性解析:|    - 字面量值|    - 引用其他 Bean (自动装配/手动装配, @Autowired, @Resource, @Value)|    - 集合、数组、Map|    - SpEL 表达式|    - 占位符|  - 类型转换|  - InstantiationAwareBeanPostProcessor.postProcessProperties|V
+-----------------------+
|   Aware接口回调      |
+-----------------------+|V
+-----------------------+
|   Initialization      |  (初始化)
+-----------------------+||  - BeanPostProcessor (before)|  - InitializingBean.afterPropertiesSet|  - @PostConstruct|  - init-method|  - BeanPostProcessor (after)|V
+-----------------------+
|Register DisposableBean| (注册一次性 Bean)
+-----------------------+|V
+-----------------------+
|       Return Bean     |  (返回 Bean 实例)
+-----------------------+
 
关键点:
BeanFactory是创建 Bean 实例的核心组件。BeanDefinition包含了创建 Bean 实例所需的所有信息。- Spring 支持多种创建 Bean 实例的方式(构造函数、工厂方法、
FactoryBean)。 - Spring 支持多种注入方式(Setter 注入、字段注入)。
 InstantiationAwareBeanPostProcessor可以在 Bean 实例化前后进行干预。BeanPostProcessor可以在 Bean 初始化前后进行处理(AOP 的关键)。- Aware 接口用于注入容器提供的资源。
 - Spring 使用三级缓存来解决单例 Bean 的循环依赖.