Spring Bean 生命周期详解

一、概述

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:获取 BeanFactory
  • ApplicationContextAware:获取 ApplicationContext
  • EnvironmentAware:获取环境变量
  • 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 初始化方法执行

执行顺序

  1. @PostConstruct 注解的方法(通过 CommonAnnotationBeanPostProcessor 处理)
  2. InitializingBean.afterPropertiesSet()
  3. 自定义 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)

作用:释放资源,执行清理逻辑

执行顺序

  1. @PreDestroy 注解的方法
  2. DisposableBean.destroy()
  3. 自定义 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);

解决流程

  1. A 创建时,将 A 的 ObjectFactory 放入三级缓存
  2. A 属性注入时需要 B
  3. 创建 B,B 属性注入时需要 A
  4. 从三级缓存获取 A 的 ObjectFactory,创建 A 的早期引用
  5. 将 A 的早期引用放入二级缓存,移除三级缓存
  6. B 完成创建,放入一级缓存
  7. 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);
        }

        // 确保所有资源都尝试清理,即使某些失败
    }
}
相关推荐
猎人everest1 小时前
Django Rest Framework (DRF) 核心知识体系梳理与深度讲解
后端·python·django
9号达人1 小时前
大家天天说的'银弹'到底是个啥?看完这篇你就明白了
前端·后端·程序员
卿雪1 小时前
缓存异常:缓存击穿、缓存穿透、缓存雪崩 及其解决方案
java·数据库·redis·python·mysql·缓存·golang
无限进步_1 小时前
C语言文件操作函数解析
c语言·开发语言·数据库·c++·后端·visual studio
小坏讲微服务1 小时前
Spring Boot 4.0 整合 RabbitMQ 注解方式使用指南
java·spring boot·rabbitmq·java-rabbitmq
星辰烈龙1 小时前
黑马程序员Java基础7
java·开发语言
big-seal1 小时前
分页列表中能够按照名称查询,使用 mybatis 的 Example 动态构造 SQL where 条件
java·开发语言
福尔摩斯张1 小时前
C语言文件操作详解(一):文件的打开与关闭(详细)
java·linux·运维·服务器·c语言·数据结构·算法
廋到被风吹走1 小时前
【Spring】依赖注入的实现方式对比
java·spring