系列文章第3篇(完结篇)| 共3篇
难度:⭐⭐⭐⭐ | 适合人群:想深入掌握Spring核心原理的开发者
📝 系列回顾
经过前两篇的学习,我们已经掌握了:
- ✅ 第一篇: IoC和DI概念、手写简易IoC容器、BeanFactory基础
- ✅ 第二篇: ApplicationContext深入、七大核心区别、启动流程
上期思考题解答:
Q1: ApplicationContext启动时,所有Bean都会创建吗?
A: 不是!@Lazy
标记的Bean、prototype
作用域的Bean不会在启动时创建。
Q2: Bean创建失败会怎样?
A: ApplicationContext启动失败(快速失败),BeanFactory运行时才报错。
Q3: Bean生命周期有哪些阶段?
A: 今天详细解答,11个完整步骤!
💥 开场:一次诡异的Bug
时间: 周四晚上8点
地点: 办公室(加班中)
事件: 线上Bug紧急修复
产品经理: "用户反馈订单创建后没收到短信通知!"
我: "让我看看..." 😰
查看代码:
java
@Service
public class OrderService {
@Autowired
private SmsService smsService;
private String notificationPhone; // 通知手机号
// 从配置文件读取
@Value("${notification.phone}")
public void setNotificationPhone(String phone) {
this.notificationPhone = phone;
System.out.println("设置通知手机号:" + phone);
}
public void createOrder(Order order) {
// 保存订单...
// 发送短信
smsService.send(notificationPhone, "新订单:" + order.getId());
}
}
测试:
java
@SpringBootTest
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
public void testCreateOrder() {
Order order = new Order(123L);
orderService.createOrder(order); // 报错:notificationPhone is null
}
}
我: "WTF?明明配置了notification.phone=13800138000
,为啥是null?" 😱
第二天,请教架构师老李:
老李: "你的@Value
注入时机有问题。"
我: "啥意思?" 🤔
老李: "你有没有在构造器里用notificationPhone
?"
我: "有啊..."
java
public OrderService() {
System.out.println("构造器:notificationPhone = " + notificationPhone);
// 输出:构造器:notificationPhone = null
}
老李: "这就是问题!Spring创建Bean的生命周期有11个步骤,@Value
注入是在属性填充阶段 ,而构造器执行在实例化阶段,构造器执行时属性还没注入!"
我: "原来如此!那生命周期具体是怎样的?" 💡
老李: "来,我给你画个图..."
🎯 第一问:Bean生命周期概览
完整的11个步骤
kotlin
Bean生命周期(11步骤)
│
├─ 1. 实例化(Instantiation)
│ └─ 调用构造器创建Bean实例
│
├─ 2. 属性填充(Populate Properties)
│ └─ @Autowired、@Value注入
│
├─ 3. 设置Bean名称(setBeanName)
│ └─ 如果实现了BeanNameAware
│
├─ 4. 设置BeanFactory(setBeanFactory)
│ └─ 如果实现了BeanFactoryAware
│
├─ 5. 设置ApplicationContext(setApplicationContext)
│ └─ 如果实现了ApplicationContextAware
│
├─ 6. BeanPostProcessor前置处理(postProcessBeforeInitialization)
│ └─ 所有BeanPostProcessor的前置方法
│
├─ 7. 初始化前(@PostConstruct)
│ └─ 执行@PostConstruct标记的方法
│
├─ 8. 初始化(afterPropertiesSet)
│ └─ 如果实现了InitializingBean
│
├─ 9. 自定义初始化方法(init-method)
│ └─ 执行自定义init方法
│
├─ 10. BeanPostProcessor后置处理(postProcessAfterInitialization)
│ └─ 所有BeanPostProcessor的后置方法(AOP代理在这里)
│
└─ 11. 销毁(Destruction)
├─ @PreDestroy方法
├─ DisposableBean的destroy()
└─ 自定义destroy-method
生命周期流程图
scss
[容器启动]
↓
┌───────────────────┐
│ 1. 实例化Bean │ ← new Person()
│ (构造器) │
└───────────────────┘
↓
┌───────────────────┐
│ 2. 属性填充 │ ← @Autowired、@Value
│ │
└───────────────────┘
↓
┌───────────────────┐
│ 3-5. Aware接口 │ ← setBeanName、setBeanFactory等
│ │
└───────────────────┘
↓
┌───────────────────┐
│ 6. Before前置处理 │ ← BeanPostProcessor
│ │
└───────────────────┘
↓
┌───────────────────┐
│ 7-9. 初始化 │ ← @PostConstruct、init
│ │
└───────────────────┘
↓
┌───────────────────┐
│ 10. After后置处理 │ ← BeanPostProcessor(AOP)
│ │
└───────────────────┘
↓
┌───────────────────┐
│ Bean就绪,可使用 │
└───────────────────┘
↓
[容器关闭]
↓
┌───────────────────┐
│ 11. 销毁 │ ← @PreDestroy、destroy
│ │
└───────────────────┘
💻 第二问:手写代码验证每个步骤
创建完整的生命周期Bean
java
package com.example.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 完整生命周期演示Bean
*/
@Component
public class LifecycleBean implements
BeanNameAware, // 步骤3
BeanFactoryAware, // 步骤4
ApplicationContextAware, // 步骤5
InitializingBean, // 步骤8
DisposableBean { // 步骤11
private String name;
// ========== 步骤1:实例化(构造器) ==========
public LifecycleBean() {
System.out.println("1. 【实例化】构造器被调用");
}
// ========== 步骤2:属性填充 ==========
// @Autowired、@Value在这个阶段注入
// Spring通过反射设置属性值
public void setName(String name) {
this.name = name;
System.out.println("2. 【属性填充】setName: " + name);
}
// ========== 步骤3:BeanNameAware ==========
@Override
public void setBeanName(String name) {
System.out.println("3. 【BeanNameAware】setBeanName: " + name);
}
// ========== 步骤4:BeanFactoryAware ==========
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. 【BeanFactoryAware】setBeanFactory: " +
beanFactory.getClass().getSimpleName());
}
// ========== 步骤5:ApplicationContextAware ==========
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("5. 【ApplicationContextAware】setApplicationContext: " +
applicationContext.getClass().getSimpleName());
}
// 步骤6:BeanPostProcessor.postProcessBeforeInitialization
// (在自定义的BeanPostProcessor中实现,见下文)
// ========== 步骤7:@PostConstruct ==========
@PostConstruct
public void postConstruct() {
System.out.println("7. 【@PostConstruct】postConstruct方法被调用");
}
// ========== 步骤8:InitializingBean ==========
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("8. 【InitializingBean】afterPropertiesSet方法被调用");
}
// ========== 步骤9:自定义init方法 ==========
public void customInit() {
System.out.println("9. 【自定义init】customInit方法被调用");
}
// 步骤10:BeanPostProcessor.postProcessAfterInitialization
// (在自定义的BeanPostProcessor中实现,见下文)
// Bean就绪,可以使用了
// ========== 步骤11:销毁阶段 ==========
@PreDestroy
public void preDestroy() {
System.out.println("11.1 【@PreDestroy】preDestroy方法被调用");
}
@Override
public void destroy() throws Exception {
System.out.println("11.2 【DisposableBean】destroy方法被调用");
}
public void customDestroy() {
System.out.println("11.3 【自定义destroy】customDestroy方法被调用");
}
}
自定义BeanPostProcessor
java
package com.example.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 自定义BeanPostProcessor
* 用于步骤6和步骤10
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 步骤6:初始化前置处理
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 只处理我们的LifecycleBean
if (bean instanceof LifecycleBean) {
System.out.println("6. 【BeanPostProcessor】postProcessBeforeInitialization: " +
beanName);
}
return bean; // 必须返回bean
}
/**
* 步骤10:初始化后置处理
* AOP代理就是在这里创建的!
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println("10. 【BeanPostProcessor】postProcessAfterInitialization: " +
beanName);
// 这里可以返回代理对象
// return Proxy.newProxyInstance(...);
}
return bean;
}
}
配置类
java
package com.example.lifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.example.lifecycle")
public class LifecycleConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleBean lifecycleBean() {
LifecycleBean bean = new LifecycleBean();
bean.setName("TestBean");
return bean;
}
}
测试类
java
package com.example.lifecycle;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class LifecycleTest {
public static void main(String[] args) {
System.out.println("========== 容器启动 ==========\n");
// 创建容器(Bean会在这里创建)
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(LifecycleConfig.class);
System.out.println("\n========== Bean已就绪 ==========\n");
// 获取Bean
LifecycleBean bean = context.getBean(LifecycleBean.class);
System.out.println("获取到Bean: " + bean);
System.out.println("\n========== 关闭容器 ==========\n");
// 关闭容器(触发销毁)
context.close();
System.out.println("\n========== 容器已关闭 ==========");
}
}
运行结果
markdown
========== 容器启动 ==========
1. 【实例化】构造器被调用
2. 【属性填充】setName: TestBean
3. 【BeanNameAware】setBeanName: lifecycleBean
4. 【BeanFactoryAware】setBeanFactory: DefaultListableBeanFactory
5. 【ApplicationContextAware】setApplicationContext: AnnotationConfigApplicationContext
6. 【BeanPostProcessor】postProcessBeforeInitialization: lifecycleBean
7. 【@PostConstruct】postConstruct方法被调用
8. 【InitializingBean】afterPropertiesSet方法被调用
9. 【自定义init】customInit方法被调用
10. 【BeanPostProcessor】postProcessAfterInitialization: lifecycleBean
========== Bean已就绪 ==========
获取到Bean: com.example.lifecycle.LifecycleBean@1a2b3c4d
========== 关闭容器 ==========
11.1 【@PreDestroy】preDestroy方法被调用
11.2 【DisposableBean】destroy方法被调用
11.3 【自定义destroy】customDestroy方法被调用
========== 容器已关闭 ==========
完美!11个步骤全部验证! ✨
🔍 第三问:源码深度解析
核心方法:doCreateBean()
位置: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
源码(简化版):
java
/**
* 实际创建Bean的方法
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// ========== 步骤1:实例化Bean ==========
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 允许提前暴露(解决循环依赖)
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 将Bean放入三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ========== 步骤2:属性填充 ==========
populateBean(beanName, mbd, instanceWrapper);
// ========== 步骤3-10:初始化Bean ==========
Object exposedObject = initializeBean(beanName, bean, mbd);
// 处理循环依赖
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
exposedObject = earlySingletonReference;
}
}
// 注册销毁回调
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
步骤1:实例化Bean
java
/**
* 创建Bean实例
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd,
Object[] args) {
Class<?> beanClass = mbd.getBeanClass();
// 1. 使用工厂方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 2. 使用构造器自动装配
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 3. 使用默认构造器
return instantiateBean(beanName, mbd);
}
/**
* 使用默认构造器实例化
*/
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
关键点:
- 优先使用工厂方法
- 其次使用有参构造器(自动装配)
- 最后使用无参构造器
- 使用反射创建实例:
Constructor.newInstance()
步骤2:属性填充
java
/**
* 填充Bean属性
*/
protected void populateBean(String beanName, RootBeanDefinition mbd,
BeanWrapper bw) {
// 1. 执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 如果返回false,跳过属性填充
}
}
}
// 2. 获取属性值
PropertyValues pvs = mbd.getPropertyValues();
// 3. 自动装配(byName或byType)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
else if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 4. 执行InstantiationAwareBeanPostProcessor的postProcessProperties
// @Autowired、@Value就是在这里注入的!
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse != null) {
pvs = pvsToUse;
}
}
}
// 5. 应用属性值
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
关键点:
@Autowired
通过AutowiredAnnotationBeanPostProcessor
处理@Value
通过AutowiredAnnotationBeanPostProcessor
处理- 使用反射设置字段值:
Field.set()
步骤3-10:初始化Bean
java
/**
* 初始化Bean
*/
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// ========== 步骤3-5:Aware接口回调 ==========
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
// ========== 步骤6:BeanPostProcessor前置处理 ==========
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// ========== 步骤7-9:初始化方法 ==========
invokeInitMethods(beanName, wrappedBean, mbd);
// ========== 步骤10:BeanPostProcessor后置处理 ==========
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
步骤3-5:Aware接口回调
java
/**
* 执行Aware接口方法
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// 步骤3:BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 步骤4:BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// 步骤4:BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
}
// 步骤5:ApplicationContextAware在ApplicationContextAwareProcessor中处理
// 这是一个BeanPostProcessor
步骤6:前置处理
java
/**
* BeanPostProcessor前置处理
*/
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean,
String beanName) throws BeansException {
Object result = existingBean;
// 遍历所有BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
重要的BeanPostProcessor:
ApplicationContextAwareProcessor
:处理ApplicationContextAwareCommonAnnotationBeanPostProcessor
:处理@PostConstruct
、@PreDestroy
InitDestroyAnnotationBeanPostProcessor
:处理JSR-250注解
步骤7-9:初始化方法
java
/**
* 执行初始化方法
*/
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
// 步骤7:@PostConstruct
// 已经在CommonAnnotationBeanPostProcessor的前置处理中执行了
// 步骤8:InitializingBean
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
// 步骤9:自定义init方法
if (mbd != null && !isInitializingBean) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
/**
* 执行自定义init方法
*/
protected void invokeCustomInitMethod(String beanName, Object bean,
RootBeanDefinition mbd) throws Throwable {
String initMethodName = mbd.getInitMethodName();
Method initMethod = mbd.getResolvedInitMethod();
if (initMethod == null) {
initMethod = beanClass.getMethod(initMethodName);
mbd.resolvedInitMethod = initMethod;
}
// 反射调用init方法
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
}
步骤10:后置处理(AOP代理)
java
/**
* BeanPostProcessor后置处理
*/
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean,
String beanName) throws BeansException {
Object result = existingBean;
// 遍历所有BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current; // 可能返回代理对象
}
return result;
}
重要的BeanPostProcessor:
AbstractAutoProxyCreator
:AOP代理在这里创建!AsyncAnnotationBeanPostProcessor
:处理@Async
AOP代理创建:
java
// AbstractAutoProxyCreator的postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果需要代理
if (shouldProxyTargetClass(beanClass, beanName)) {
// 创建代理对象
return createProxy(bean.getClass(), beanName,
specificInterceptors, targetSource);
}
}
return bean;
}
步骤11:销毁Bean
java
/**
* 销毁Bean
*/
public void destroyBean(String beanName, Object beanInstance) {
// 步骤11.1:@PreDestroy
// 由CommonAnnotationBeanPostProcessor处理
// 步骤11.2:DisposableBean
if (beanInstance instanceof DisposableBean) {
((DisposableBean) beanInstance).destroy();
}
// 步骤11.3:自定义destroy方法
String destroyMethodName = mbd.getDestroyMethodName();
if (destroyMethodName != null) {
invokeCustomDestroyMethod(beanInstance, destroyMethodName);
}
}
🎯 第四问:循环依赖与三级缓存
什么是循环依赖?
java
@Component
public class A {
@Autowired
private B b; // A依赖B
}
@Component
public class B {
@Autowired
private A a; // B依赖A
}
问题:
css
创建A → 需要注入B → 创建B → 需要注入A → 创建A → ...
无限循环! 🔄
Spring的解决方案:三级缓存
三级缓存定义:
java
public class DefaultSingletonBeanRegistry {
/** 一级缓存:单例对象缓存(成品) */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存:早期单例对象缓存(半成品) */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** 三级缓存:单例工厂缓存(工厂) */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}
三级缓存解决流程
场景:A和B循环依赖
css
1. 创建A
├─ 实例化A(调用构造器)
├─ 将A的工厂放入三级缓存
├─ 填充A的属性
│ └─ 需要注入B
│ ├─ 创建B
│ │ ├─ 实例化B
│ │ ├─ 将B的工厂放入三级缓存
│ │ ├─ 填充B的属性
│ │ │ └─ 需要注入A
│ │ │ ├─ 从三级缓存获取A的工厂
│ │ │ ├─ 调用工厂创建A的早期引用
│ │ │ ├─ 放入二级缓存
│ │ │ └─ 返回A的早期引用给B ✅
│ │ ├─ B的属性填充完成
│ │ └─ B初始化完成,放入一级缓存
│ └─ 返回B给A ✅
├─ A的属性填充完成
└─ A初始化完成,放入一级缓存
获取Bean的源码
java
/**
* 获取单例Bean
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 从一级缓存获取(成品)
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 2. 从二级缓存获取(半成品)
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) {
// 3. 从三级缓存获取工厂
ObjectFactory<?> singletonFactory =
this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用工厂创建对象
singletonObject = singletonFactory.getObject();
// 放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 移除三级缓存
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
为什么需要三级缓存?
Q:二级缓存不够吗?
A: 为了支持AOP代理!
场景:
java
@Component
public class A {
@Autowired
private B b;
}
@Component
public class B {
@Autowired
private A a; // 这里需要的是A的代理对象,不是原始对象
}
解决:
java
// 三级缓存中存的是ObjectFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// getEarlyBeanReference会调用所有SmartInstantiationAwareBeanPostProcessor
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// 这里可以返回代理对象!
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
总结:
- 一级缓存:存放完全初始化好的Bean
- 二级缓存:存放实例化但未初始化的Bean(可能是代理对象)
- 三级缓存:存放Bean工厂,用于创建早期引用(支持AOP)
💻 第五问:实战案例分析
案例1:@PostConstruct vs InitializingBean vs init-method
哪个先执行?
java
@Component
public class InitOrderBean implements InitializingBean {
@PostConstruct
public void postConstruct() {
System.out.println("1. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
System.out.println("2. InitializingBean.afterPropertiesSet");
}
public void customInit() {
System.out.println("3. custom init-method");
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit")
public InitOrderBean initOrderBean() {
return new InitOrderBean();
}
}
输出:
markdown
1. @PostConstruct
2. InitializingBean.afterPropertiesSet
3. custom init-method
推荐使用顺序:
- 优先:
@PostConstruct
(JSR-250标准,推荐) - 次选:
InitializingBean
(Spring特定接口,侵入性) - 最后:
init-method
(XML配置时代的产物)
案例2:属性注入时机问题(开篇Bug)
错误的写法:
java
@Service
public class OrderService {
@Value("${notification.phone}")
private String notificationPhone;
public OrderService() {
// ❌ 错误:构造器执行时,@Value还没注入
System.out.println("构造器:phone = " + notificationPhone); // null
}
}
正确的写法1:使用@PostConstruct
java
@Service
public class OrderService {
@Value("${notification.phone}")
private String notificationPhone;
@PostConstruct
public void init() {
// ✅ 正确:@PostConstruct在属性注入之后
System.out.println("PostConstruct:phone = " + notificationPhone); // 有值
}
}
正确的写法2:使用构造器注入
java
@Service
public class OrderService {
private final String notificationPhone;
// ✅ 正确:构造器注入在实例化时就完成
@Autowired
public OrderService(@Value("${notification.phone}") String phone) {
this.notificationPhone = phone;
System.out.println("构造器:phone = " + notificationPhone); // 有值
}
}
案例3:BeanPostProcessor修改Bean
自定义BeanPostProcessor修改Bean属性:
java
@Component
public class UserEnhancePostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof UserService) {
UserService userService = (UserService) bean;
// 修改Bean的属性
userService.setMaxRetry(5);
System.out.println("增强UserService:设置最大重试次数为5");
}
return bean;
}
}
案例4:动态代理Bean
创建代理Bean:
java
@Component
public class LogProxyPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 只为Service层创建代理
if (bean.getClass().isAnnotationPresent(Service.class)) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println(">>> 调用方法:" + method.getName());
long start = System.currentTimeMillis();
Object result = method.invoke(bean, args);
long end = System.currentTimeMillis();
System.out.println("<<< 方法执行耗时:" + (end - start) + "ms");
return result;
}
);
}
return bean;
}
}
效果:
java
@Service
public class UserService {
public User getUser(Long id) {
return new User(id, "张三");
}
}
// 使用
userService.getUser(1L);
// 输出:
// >>> 调用方法:getUser
// <<< 方法执行耗时:5ms
📊 生命周期完整总结
11步骤速记表
步骤 | 名称 | 说明 | 关键接口/注解 | 可选/必需 |
---|---|---|---|---|
1 | 实例化 | 调用构造器 | Constructor | 必需 |
2 | 属性填充 | 注入依赖 | @Autowired、@Value | 可选 |
3 | BeanNameAware | 设置Bean名称 | BeanNameAware | 可选 |
4 | BeanFactoryAware | 设置BeanFactory | BeanFactoryAware | 可选 |
5 | ApplicationContextAware | 设置ApplicationContext | ApplicationContextAware | 可选 |
6 | Before前置处理 | 初始化前处理 | BeanPostProcessor | 可选 |
7 | @PostConstruct | JSR-250初始化 | @PostConstruct | 可选 |
8 | InitializingBean | Spring初始化 | InitializingBean | 可选 |
9 | init-method | 自定义初始化 | @Bean(initMethod) | 可选 |
10 | After后置处理 | 初始化后处理(AOP) | BeanPostProcessor | 可选 |
11 | 销毁 | Bean销毁 | @PreDestroy等 | 可选 |
记忆口诀
实例化,属性填,
Aware接口三个传。
前置处理拦一道,
三种初始化按顺序来。
后置处理做代理,
Bean就绪可以用。
容器关闭销毁调,
生命周期走一遭。
💡 最佳实践建议
1. 初始化方法选择
推荐顺序:
java
// 第一选择:@PostConstruct(推荐)
@PostConstruct
public void init() {
// JSR-250标准,Spring、JavaEE通用
}
// 第二选择:InitializingBean
@Override
public void afterPropertiesSet() {
// Spring特定,侵入性强
}
// 第三选择:init-method
@Bean(initMethod = "customInit")
// XML时代产物,不推荐
2. 依赖注入方式选择
推荐:构造器注入
java
@Service
public class UserService {
private final UserDao userDao; // final保证不可变
// 构造器注入(推荐)
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
优点:
- ✅ 依赖明确
- ✅ 支持final
- ✅ 便于单元测试
- ✅ 避免循环依赖
3. 避免在构造器中使用注入的依赖
java
// ❌ 错误
@Service
public class OrderService {
@Autowired
private UserService userService;
public OrderService() {
userService.getUser(1L); // NullPointerException
}
}
// ✅ 正确
@Service
public class OrderService {
@Autowired
private UserService userService;
@PostConstruct
public void init() {
userService.getUser(1L); // 正常工作
}
}
4. 自定义BeanPostProcessor注意事项
java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// ⚠️ 注意:不要在这里创建新对象并返回
// 除非你明确知道自己在做什么(如创建代理)
// ✅ 修改bean属性
if (bean instanceof UserService) {
((UserService) bean).setMaxRetry(5);
}
// ✅ 必须返回bean
return bean;
}
}
5. 循环依赖处理
能解决的情况:
java
// ✅ 可以:字段注入 + 单例
@Component
public class A {
@Autowired
private B b;
}
@Component
public class B {
@Autowired
private A a;
}
无法解决的情况:
java
// ❌ 不行:构造器注入 + 循环依赖
@Component
public class A {
@Autowired
public A(B b) { } // 报错
}
@Component
public class B {
@Autowired
public B(A a) { } // 报错
}
// ❌ 不行:原型模式 + 循环依赖
@Component
@Scope("prototype")
public class A {
@Autowired
private B b; // 报错
}
解决方案: 重新设计类的依赖关系,避免循环依赖
🎉 系列总结
三篇文章回顾
第一篇:IoC基础
- ✅ 理解了IoC和DI概念
- ✅ 手写了100行简易IoC容器
- ✅ 学习了BeanFactory接口
第二篇:ApplicationContext
- ✅ 掌握了ApplicationContext的7大优势
- ✅ 理解了容器启动流程
- ✅ 学会了如何选择容器
第三篇:Bean生命周期
- ✅ 完整掌握11个生命周期步骤
- ✅ 深入源码级别理解
- ✅ 理解了三级缓存解决循环依赖
学习路线建议
yaml
Level 1: 基础使用 ⭐
└─ 会用@Component、@Autowired
Level 2: 理解原理 ⭐⭐
└─ 理解IoC、DI概念
Level 3: 掌握容器 ⭐⭐⭐
└─ 理解BeanFactory和ApplicationContext
Level 4: 深入生命周期 ⭐⭐⭐⭐
└─ 掌握Bean的11个生命周期步骤
Level 5: 源码级理解 ⭐⭐⭐⭐⭐
└─ 阅读Spring源码,理解实现细节
恭喜你,完成这个系列,你已经达到Level 4! 🎉
下一步学习
推荐深入主题:
- AOP原理: 代理模式、切面编程
- 事务管理: @Transactional原理
- SpringMVC: DispatcherServlet工作流程
- SpringBoot自动配置: @EnableAutoConfiguration原理
- Spring源码阅读: 从ApplicationContext入手
💬 写在最后
从第一篇到现在,我们一起:
- 🔧 手写了简易IoC容器
- 📚 理解了容器的演进
- 🔬 深入了Bean的生命周期
这个系列到这里就完结了!
如果这个系列对你有帮助,请:
- 👍 点赞支持
- ⭐ 收藏备用
- 🔄 转发分享
- 💬 评论交流
感谢一路陪伴,期待下个系列再见! 👋