一、概述
Spring Bean 生命周期是指 Bean 从创建、初始化、使用到销毁的整个过程。Spring 容器负责管理 Bean 的完整生命周期,提供了多个扩展点让开发者可以在 Bean 生命周期的不同阶段介入自定义逻辑。
1.1 生命周期阶段总览
实例化 → 属性赋值 → 初始化 → 使用 → 销毁
二、生命周期完整流程
2.1 详细流程图
1. 实例化 Bean(Instantiation)
├─ InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
├─ 构造器或工厂方法创建实例
└─ InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
2. 属性赋值(Populate)
├─ InstantiationAwareBeanPostProcessor.postProcessProperties()
└─ 设置属性值
3. 初始化(Initialization)
├─ Aware 接口回调
│ ├─ BeanNameAware.setBeanName()
│ ├─ BeanClassLoaderAware.setBeanClassLoader()
│ └─ BeanFactoryAware.setBeanFactory()
│
├─ BeanPostProcessor.postProcessBeforeInitialization()
│ └─ ApplicationContextAwareProcessor 处理其他 Aware 接口
│ ├─ EnvironmentAware.setEnvironment()
│ ├─ ApplicationContextAware.setApplicationContext()
│ └─ 等其他 Aware 接口
│
├─ 初始化方法
│ ├─ @PostConstruct 注解的方法
│ ├─ InitializingBean.afterPropertiesSet()
│ └─ 自定义 init-method
│
└─ BeanPostProcessor.postProcessAfterInitialization()
└─ 返回代理对象(AOP 在此阶段生成代理)
4. 使用(In Use)
└─ Bean 已完全初始化,可以使用
5. 销毁(Destruction)
├─ @PreDestroy 注解的方法
├─ DisposableBean.destroy()
└─ 自定义 destroy-method
2.2 核心接口与方法执行顺序
| 顺序 | 阶段 | 接口/方法 | 说明 |
|---|---|---|---|
| 1 | 实例化前 | InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() | 可返回代理对象代替默认实例化 |
| 2 | 实例化 | 构造器 | 通过反射调用构造器 |
| 3 | 实例化后 | InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() | 控制是否继续属性赋值 |
| 4 | 属性赋值前 | InstantiationAwareBeanPostProcessor.postProcessProperties() | 可修改属性值 |
| 5 | 属性赋值 | populate properties | 依赖注入 |
| 6 | Aware 注入 | BeanNameAware.setBeanName() | 注入 Bean 名称 |
| 7 | Aware 注入 | BeanClassLoaderAware.setBeanClassLoader() | 注入类加载器 |
| 8 | Aware 注入 | BeanFactoryAware.setBeanFactory() | 注入 BeanFactory |
| 9 | 初始化前 | BeanPostProcessor.postProcessBeforeInitialization() | 初始化前处理 |
| 10 | 初始化 | @PostConstruct | JSR-250 注解 |
| 11 | 初始化 | InitializingBean.afterPropertiesSet() | Spring 接口 |
| 12 | 初始化 | init-method | 自定义初始化方法 |
| 13 | 初始化后 | BeanPostProcessor.postProcessAfterInitialization() | AOP 代理在此创建 |
| 14 | 销毁 | @PreDestroy | JSR-250 注解 |
| 15 | 销毁 | DisposableBean.destroy() | Spring 接口 |
| 16 | 销毁 | destroy-method | 自定义销毁方法 |
三、各阶段详细说明
3.1 实例化阶段(Instantiation)
作用:创建 Bean 的实例对象
核心类 :AbstractAutowireCapableBeanFactory
关键方法:
java
// 创建 Bean 实例的入口方法
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 让 BeanPostProcessor 有机会返回代理对象
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
// 2. 实际创建 Bean
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}
// 实例化前处理
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 调用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 如果返回了对象,则调用 postProcessAfterInitialization
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
return bean;
}
实例化方式:
- 构造器实例化(最常见)
- 工厂方法实例化
- FactoryBean 实例化
3.2 属性赋值阶段(Populate)
作用:为 Bean 的属性注入值,包括依赖注入
关键方法:
java
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 实例化后处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 如果返回 false,跳过属性赋值
}
}
}
// 2. 获取属性值
PropertyValues pvs = mbd.getPropertyValues();
// 3. 自动装配(byName 或 byType)
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 4. 后处理属性值
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
pvs = pvsToUse;
}
// 5. 应用属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
依赖注入类型:
@Autowired/@Resource注解注入- setter 方法注入
- 构造器注入
3.3 初始化阶段(Initialization)
作用:执行初始化逻辑,为 Bean 提供自定义配置的机会
3.3.1 Aware 接口回调
作用:让 Bean 能够获取 Spring 容器的相关资源
java
// invokeAwareMethods 方法
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
}
常用 Aware 接口:
BeanNameAware:获取 Bean 在容器中的名称BeanFactoryAware:获取 BeanFactoryApplicationContextAware:获取 ApplicationContextEnvironmentAware:获取环境变量ResourceLoaderAware:获取资源加载器
3.3.2 BeanPostProcessor 处理
核心接口:
java
public interface BeanPostProcessor {
// 初始化前处理
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
// 初始化后处理(AOP 代理在此创建)
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
执行流程:
java
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 接口回调
invokeAwareMethods(beanName, bean);
// 2. 初始化前处理
Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 3. 调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 4. 初始化后处理(AOP 代理)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
3.3.3 初始化方法执行
执行顺序:
@PostConstruct注解的方法(通过 CommonAnnotationBeanPostProcessor 处理)InitializingBean.afterPropertiesSet()- 自定义
init-method
java
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
// 1. 调用 InitializingBean 接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
// 2. 调用自定义 init-method
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName))) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
3.4 销毁阶段(Destruction)
作用:释放资源,执行清理逻辑
执行顺序:
@PreDestroy注解的方法DisposableBean.destroy()- 自定义
destroy-method
java
public void destroy() {
// 1. 调用 @PreDestroy 方法
// 由 DestructionAwareBeanPostProcessor 处理
// 2. 调用 DisposableBean 接口
if (this.bean instanceof DisposableBean) {
((DisposableBean) this.bean).destroy();
}
// 3. 调用自定义 destroy-method
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
}
四、核心原理分析
4.1 核心类关系
AbstractApplicationContext
└─ refresh() // 容器刷新入口
└─ finishBeanFactoryInitialization() // 实例化所有单例 Bean
└─ DefaultListableBeanFactory.preInstantiateSingletons()
└─ AbstractBeanFactory.getBean()
└─ AbstractBeanFactory.doGetBean()
└─ AbstractAutowireCapableBeanFactory.createBean()
└─ AbstractAutowireCapableBeanFactory.doCreateBean()
├─ createBeanInstance() // 实例化
├─ populateBean() // 属性赋值
└─ initializeBean() // 初始化
4.2 Bean 定义与实例的关系
BeanDefinition(Bean 定义)
├─ 描述 Bean 的元数据
├─ Class 类型
├─ 作用域(Scope)
├─ 构造器参数
├─ 属性值
└─ 初始化/销毁方法
↓ 通过 BeanFactory 创建
Bean Instance(Bean 实例)
└─ 实际的对象实例
4.3 BeanPostProcessor 的作用机制
BeanPostProcessor 是 Spring 提供的扩展点,允许在 Bean 初始化前后插入自定义逻辑。
重要实现类:
ApplicationContextAwareProcessor:处理 Aware 接口CommonAnnotationBeanPostProcessor:处理 JSR-250 注解(@PostConstruct、@PreDestroy)AutowiredAnnotationBeanPostProcessor:处理 @Autowired、@Value 注解AbstractAutoProxyCreator:AOP 代理创建(返回代理对象)
4.4 循环依赖处理
Spring 使用三级缓存解决循环依赖:
java
// 一级缓存:成品对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:半成品对象(已实例化,未初始化)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存:对象工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
解决流程:
- A 创建时,将 A 的 ObjectFactory 放入三级缓存
- A 属性注入时需要 B
- 创建 B,B 属性注入时需要 A
- 从三级缓存获取 A 的 ObjectFactory,创建 A 的早期引用
- 将 A 的早期引用放入二级缓存,移除三级缓存
- B 完成创建,放入一级缓存
- A 注入 B,完成创建,放入一级缓存
五、源码级原理分析
5.1 容器启动流程
java
// AbstractApplicationContext.refresh()
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();
// 10. 注册监听器
registerListeners();
// 11. 实例化所有非懒加载的单例 Bean ★★★
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新
finishRefresh();
} catch (BeansException ex) {
// 销毁已创建的 Bean
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
}
}
}
5.2 Bean 创建核心流程
java
// AbstractAutowireCapableBeanFactory.doCreateBean()
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args)
throws BeanCreationException {
// 1. 实例化 Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建实例(调用构造器)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
// 2. 处理循环依赖:将早期引用暴露到三级缓存
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 3. 属性赋值
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
// 4. 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
// 异常处理
}
// 5. 循环依赖检查
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
}
// 6. 注册销毁回调
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid destruction signature", ex);
}
return exposedObject;
}
5.3 实例化细节
java
// AbstractAutowireCapableBeanFactory.createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 确保 Bean 类已加载
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 2. 使用工厂方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 3. 构造器自动装配
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() ||
!ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 4. 使用默认构造器
return instantiateBean(beanName, mbd);
}
// 使用默认构造器实例化
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
} else {
// 使用实例化策略(默认使用 CGLIB)
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Instantiation of bean failed", ex);
}
}
5.4 属性注入细节
java
// AutowiredAnnotationBeanPostProcessor.postProcessProperties()
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 1. 查找需要注入的元数据(@Autowired、@Value 等)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 2. 执行注入
try {
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
// InjectionMetadata.inject()
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs)
throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 注入字段或方法
element.inject(target, beanName, pvs);
}
}
}
5.5 AOP 代理创建
java
// AbstractAutoProxyCreator.postProcessAfterInitialization()
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果需要代理,则创建代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 获取增强器(Advisor)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 2. 如果有增强器,则创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(),
beanName,
specificInterceptors,
new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
六、实际使用示例
6.1 完整生命周期演示
依赖类定义:
java
import org.springframework.stereotype.Component;
@Component
public class SomeDependency {
public void doSomething() {
System.out.println("SomeDependency is working");
}
}
生命周期Bean完整示例:
java
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;
@Component
public class LifecycleBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
private SomeDependency someDependency;
// 1. 构造器
public LifecycleBean() {
System.out.println("1. 构造器:创建 Bean 实例");
}
// 2. 属性注入(通过 setter 或 @Autowired)
@Autowired
public void setSomeDependency(SomeDependency dependency) {
this.someDependency = dependency;
System.out.println("2. 属性注入:注入依赖");
}
// 3. BeanNameAware
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("3. BeanNameAware:设置 Bean 名称 = " + name);
}
// 4. BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("4. BeanFactoryAware:设置 BeanFactory");
}
// 5. ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("5. ApplicationContextAware:设置 ApplicationContext");
}
// 6. @PostConstruct
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct:执行初始化逻辑");
}
// 7. InitializingBean
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7. InitializingBean.afterPropertiesSet():属性设置完成");
}
// 8. 自定义 init-method(在 XML 或 @Bean 中配置)
public void customInit() {
System.out.println("8. init-method:自定义初始化方法");
}
// Bean 已就绪,可以使用
public void businessMethod() {
System.out.println(">>> Bean 正在使用中...");
}
// 9. @PreDestroy
@PreDestroy
public void preDestroy() {
System.out.println("9. @PreDestroy:准备销毁");
}
// 10. DisposableBean
@Override
public void destroy() throws Exception {
System.out.println("10. DisposableBean.destroy():执行销毁逻辑");
}
// 11. 自定义 destroy-method
public void customDestroy() {
System.out.println("11. destroy-method:自定义销毁方法");
}
}
配置示例(Java Config):
java
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleBean lifecycleBean() {
return new LifecycleBean();
}
}
输出结果:
1. 构造器:创建 Bean 实例
2. 属性注入:注入依赖
3. BeanNameAware:设置 Bean 名称 = lifecycleBean
4. BeanFactoryAware:设置 BeanFactory
5. ApplicationContextAware:设置 ApplicationContext
6. @PostConstruct:执行初始化逻辑
7. InitializingBean.afterPropertiesSet():属性设置完成
8. init-method:自定义初始化方法
>>> Bean 正在使用中...
9. @PreDestroy:准备销毁
10. DisposableBean.destroy():执行销毁逻辑
11. destroy-method:自定义销毁方法
6.2 自定义 BeanPostProcessor
java
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println(">>> BeanPostProcessor.postProcessBeforeInitialization: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println(">>> BeanPostProcessor.postProcessAfterInitialization: " + beanName);
// 可以在这里返回代理对象
}
return bean;
}
}
6.3 使用 @Bean 注解配置生命周期
java
@Configuration
public class DatabaseConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
ds.setUsername("root");
ds.setPassword("password");
return ds;
}
}
// HikariDataSource 类中的方法
public class HikariDataSource implements DataSource {
public void init() {
// 初始化连接池
System.out.println("初始化数据库连接池");
}
public void close() {
// 关闭连接池
System.out.println("关闭数据库连接池");
}
}
6.4 实际应用:资源管理
java
@Component
public class CacheManager implements InitializingBean, DisposableBean {
private Cache cache;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化缓存
cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
System.out.println("缓存已初始化");
}
@Override
public void destroy() throws Exception {
// 清理缓存
if (cache != null) {
cache.invalidateAll();
System.out.println("缓存已清理");
}
}
public Object get(String key) {
return cache.getIfPresent(key);
}
public void put(String key, Object value) {
cache.put(key, value);
}
}
6.5 异步初始化示例
java
@Component
public class AsyncInitBean {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@PostConstruct
public void init() {
System.out.println("开始异步初始化...");
// 异步加载大量数据
taskExecutor.submit(() -> {
// 模拟耗时操作
loadHeavyData();
System.out.println("异步初始化完成");
});
System.out.println("init 方法返回,Bean 已就绪");
}
private void loadHeavyData() {
try {
Thread.sleep(5000);
// 加载数据逻辑
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
七、作用与应用场景
7.1 生命周期回调的作用
| 阶段 | 作用 | 应用场景 |
|---|---|---|
| 构造器 | 创建对象实例 | 对象基本初始化 |
| 属性注入 | 依赖注入 | 注入其他 Bean、配置值 |
| Aware 接口 | 获取容器资源 | 获取 BeanName、ApplicationContext 等 |
| @PostConstruct | 初始化逻辑 | 数据加载、资源初始化、缓存预热 |
| InitializingBean | Spring 标准初始化 | 验证配置、建立连接 |
| init-method | 自定义初始化 | 灵活的初始化逻辑 |
| BeanPostProcessor | AOP、代理 | 创建代理、增强功能 |
| @PreDestroy | 清理准备 | 停止定时任务、标记状态 |
| DisposableBean | Spring 标准销毁 | 释放资源、关闭连接 |
| destroy-method | 自定义销毁 | 灵活的清理逻辑 |
7.2 常见应用场景
7.2.1 数据库连接池管理
java
@Component
public class DatabaseConnectionPool implements InitializingBean, DisposableBean {
private HikariDataSource dataSource;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化连接池
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10);
dataSource = new HikariDataSource(config);
System.out.println("数据库连接池已启动");
}
@Override
public void destroy() throws Exception {
// 关闭连接池
if (dataSource != null && !dataSource.isClosed()) {
dataSource.close();
System.out.println("数据库连接池已关闭");
}
}
}
7.2.2 缓存预热
java
@Component
public class CacheWarmer implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
@Autowired
private CacheManager cacheManager;
@Autowired
private UserService userService;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() throws Exception {
// 应用启动后预热缓存
System.out.println("开始缓存预热...");
// 加载热点数据到缓存
List<User> hotUsers = userService.getHotUsers();
for (User user : hotUsers) {
cacheManager.put("user:" + user.getId(), user);
}
System.out.println("缓存预热完成,已加载 " + hotUsers.size() + " 条数据");
}
}
7.2.3 定时任务管理
java
@Component
public class ScheduledTaskManager implements InitializingBean, DisposableBean {
private ScheduledExecutorService scheduler;
private ScheduledFuture<?> scheduledTask;
@Override
public void afterPropertiesSet() throws Exception {
// 启动定时任务
scheduler = Executors.newScheduledThreadPool(1);
scheduledTask = scheduler.scheduleAtFixedRate(
this::executeTask,
0,
10,
TimeUnit.SECONDS
);
System.out.println("定时任务已启动");
}
private void executeTask() {
System.out.println("执行定时任务:" + LocalDateTime.now());
}
@Override
public void destroy() throws Exception {
// 停止定时任务
if (scheduledTask != null && !scheduledTask.isCancelled()) {
scheduledTask.cancel(true);
}
if (scheduler != null && !scheduler.isShutdown()) {
scheduler.shutdown();
scheduler.awaitTermination(5, TimeUnit.SECONDS);
}
System.out.println("定时任务已停止");
}
}
7.2.4 配置验证
java
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig implements InitializingBean {
private String apiUrl;
private String apiKey;
private int timeout;
@Override
public void afterPropertiesSet() throws Exception {
// 验证配置
if (apiUrl == null || apiUrl.isEmpty()) {
throw new IllegalStateException("app.apiUrl 不能为空");
}
if (apiKey == null || apiKey.isEmpty()) {
throw new IllegalStateException("app.apiKey 不能为空");
}
if (timeout <= 0) {
throw new IllegalStateException("app.timeout 必须大于 0");
}
System.out.println("配置验证通过");
}
// getters and setters
}
7.2.5 第三方服务连接
java
@Component
public class RedisConnectionManager implements InitializingBean, DisposableBean {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private int port;
private Jedis jedis;
@Override
public void afterPropertiesSet() throws Exception {
// 建立 Redis 连接
jedis = new Jedis(host, port);
jedis.connect();
// 测试连接
String pong = jedis.ping();
if (!"PONG".equals(pong)) {
throw new IllegalStateException("Redis 连接失败");
}
System.out.println("Redis 连接成功:" + host + ":" + port);
}
@Override
public void destroy() throws Exception {
// 关闭连接
if (jedis != null && jedis.isConnected()) {
jedis.close();
System.out.println("Redis 连接已关闭");
}
}
public Jedis getJedis() {
return jedis;
}
}
7.3 最佳实践
7.3.1 选择合适的初始化方式
| 方式 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| @PostConstruct | JSR-250 标准,与框架解耦 | 需要依赖 javax.annotation | 通用初始化逻辑 |
| InitializingBean | Spring 原生支持 | 与 Spring 耦合 | Spring 项目内部使用 |
| init-method | 完全解耦,灵活 | 配置繁琐 | 第三方 Bean |
推荐顺序 :@PostConstruct > InitializingBean > init-method
7.3.2 资源管理建议
java
@Component
public class ResourceManager implements InitializingBean, DisposableBean {
private ExecutorService executorService;
private final List<Closeable> resources = new ArrayList<>();
@Override
public void afterPropertiesSet() throws Exception {
// 集中管理资源
executorService = Executors.newFixedThreadPool(10);
}
public void registerResource(Closeable resource) {
resources.add(resource);
}
@Override
public void destroy() throws Exception {
// 统一释放资源
Exception firstException = null;
// 关闭线程池
if (executorService != null) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
// 关闭其他资源
for (Closeable resource : resources) {
try {
resource.close();
} catch (Exception e) {
if (firstException == null) {
firstException = e;
}
}
}
if (firstException != null) {
throw firstException;
}
}
}
7.3.3 避免常见陷阱
1. 避免在构造器中使用依赖注入的 Bean
java
// ❌ 错误示例
@Component
public class BadExample {
@Autowired
private UserService userService;
public BadExample() {
// 此时 userService 还未注入,为 null
userService.doSomething(); // NullPointerException
}
}
// ✅ 正确示例
@Component
public class GoodExample {
@Autowired
private UserService userService;
@PostConstruct
public void init() {
// 此时 userService 已注入
userService.doSomething();
}
}
2. 循环依赖注意事项
java
// 构造器注入无法解决循环依赖
@Component
public class A {
private final B b;
@Autowired
public A(B b) { // 如果 B 也构造器注入 A,会报错
this.b = b;
}
}
// 使用字段注入或 setter 注入可以解决
@Component
public class A {
@Autowired
private B b; // 可以解决循环依赖
}
3. 销毁方法异常处理
java
@Component
public class SafeDestroy implements DisposableBean {
@Override
public void destroy() throws Exception {
try {
// 清理资源 1
cleanupResource1();
} catch (Exception e) {
log.error("清理资源 1 失败", e);
}
try {
// 清理资源 2
cleanupResource2();
} catch (Exception e) {
log.error("清理资源 2 失败", e);
}
// 确保所有资源都尝试清理,即使某些失败
}
}