【Spring篇】Spring的生命周期

一、Bean 生命周期的核心阶段

1. 实例化(Instantiation)

触发时机 :容器启动时(单例 Bean)或请求时(原型 Bean)。

实现方式

通过反射(Class.newInstance() 或构造器)创建 Bean 的实例。

2. 属性赋值(Population)

依赖注入

通过字段注入(@Autowired)、Setter 注入或构造器注入为 Bean 的属性赋值。

处理 Aware 接口

若 Bean 实现了 BeanNameAwareBeanFactoryAware 等接口,容器会回调对应方法。

java 复制代码
public class MyBean implements BeanNameAware {
    private String beanName;
    @Override
    public void setBeanName(String name) {
        this.beanName = name; // 获取 Bean 的名称
    }
}
3. BeanPostProcessor 的前置处理

调用 postProcessBeforeInitialization

在 Bean 初始化前执行自定义逻辑(如修改 Bean 属性)。

java 复制代码
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 对 Bean 进行前置处理
        return bean;
    }
}
4. 初始化(Initialization)

@PostConstruct 注解方法

标记在方法上,容器会调用该方法。

java 复制代码
@PostConstruct
public void init() {
    // 初始化逻辑
}

InitializingBean 接口

实现 afterPropertiesSet() 方法。

java 复制代码
public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() {
        // 属性赋值完成后执行
    }
}

XML 配置的 init-method

在 XML 中指定初始化方法。

xml 复制代码
<bean id="myBean" class="com.example.MyBean" init-method="customInit"/>
5. BeanPostProcessor 的后置处理

调用 postProcessAfterInitialization

在 Bean 初始化后执行自定义逻辑(如生成代理对象)。

java 复制代码
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    // 对 Bean 进行后置处理(如 AOP 代理)
    return bean;
}
6. Bean 就绪(In Use)

业务使用阶段

Bean 被应用程序代码调用,执行业务逻辑。

7. 销毁(Destruction)

@PreDestroy 注解方法

标记在方法上,容器销毁前调用。

java 复制代码
@PreDestroy
public void cleanup() {
    // 释放资源逻辑
}

DisposableBean 接口

实现 destroy() 方法。

java 复制代码
public class MyBean implements DisposableBean {
    @Override
    public void destroy() {
        // 容器销毁时执行
    }
}

XML 配置的 destroy-method

在 XML 中指定销毁方法。

xml 复制代码
<bean id="myBean" class="com.example.MyBean" destroy-method="customDestroy"/>

二、生命周期的完整流程图

复制代码
实例化 → 属性赋值 → BeanPostProcessor前置处理 → 初始化 → BeanPostProcessor后置处理 → 使用 → 销毁

三、扩展点与高级特性

1. Aware 接口

作用 :让 Bean 感知容器环境。

常见接口

BeanNameAware:获取 Bean 的名称。

BeanFactoryAware:获取 BeanFactory 引用。

ApplicationContextAware:获取 ApplicationContext 引用。

2. BeanPostProcessor

核心用途

在 Bean 初始化前后插入自定义逻辑(如 AOP 代理、属性加密)。

典型场景

Spring AOP 通过 AbstractAutoProxyCreator(BeanPostProcessor 的子类)生成代理对象。

3. BeanFactoryPostProcessor

作用

在 Bean 定义加载后、实例化前修改 Bean 的定义(如修改属性值)。

java 复制代码
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        BeanDefinition beanDef = beanFactory.getBeanDefinition("myBean");
        beanDef.getPropertyValues().add("property", "newValue");
    }
}
4. 作用域对生命周期的影响

单例(Singleton)

容器启动时创建,容器关闭时销毁。

原型(Prototype)

每次请求时创建,容器不管理其销毁。

其他作用域

Request/Session (Web 环境):生命周期与请求或会话绑定。

自定义作用域 :通过 Scope 接口扩展。


四、示例代码:完整生命周期演示

1. Bean 类
java 复制代码
public class LifecycleBean implements BeanNameAware, InitializingBean, DisposableBean {
    private String beanName;

    @Override
    public void setBeanName(String name) {
        this.beanName = name; // BeanNameAware 回调
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct 方法调用");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("InitializingBean.afterPropertiesSet() 调用");
    }

    public void customInit() {
        System.out.println("XML init-method 调用");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy 方法调用");
    }

    @Override
    public void destroy() {
        System.out.println("DisposableBean.destroy() 调用");
    }

    public void customDestroy() {
        System.out.println("XML destroy-method 调用");
    }
}
2. BeanPostProcessor
java 复制代码
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof LifecycleBean) {
            System.out.println("BeanPostProcessor.postProcessBeforeInitialization() 调用");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof LifecycleBean) {
            System.out.println("BeanPostProcessor.postProcessAfterInitialization() 调用");
        }
        return bean;
    }
}
3. 输出结果
复制代码
实例化 LifecycleBean
BeanNameAware.setBeanName() 调用
BeanPostProcessor.postProcessBeforeInitialization() 调用
@PostConstruct 方法调用
InitializingBean.afterPropertiesSet() 调用
XML init-method 调用
BeanPostProcessor.postProcessAfterInitialization() 调用
...(Bean 使用阶段)...
@PreDestroy 方法调用
DisposableBean.destroy() 调用
XML destroy-method 调用

五、总结

  1. 核心阶段:实例化 → 属性注入 → 初始化 → 销毁。
  2. 关键扩展点
    • Aware 接口(获取容器信息)。
    BeanPostProcessor(初始化前后处理)。
    @PostConstruct/@PreDestroy(注解回调)。
    InitializingBean/DisposableBean(接口回调)。
  3. 作用域影响:单例和原型 Bean 的生命周期差异。
  4. 设计思想:通过回调接口和扩展点实现松耦合和可定制化。

通过掌握 Bean 的生命周期,可以更好地利用 Spring 的扩展能力(如自定义初始化、资源管理),同时避免因生命周期管理不当导致的资源泄漏或状态错误。

相关推荐
风象南4 分钟前
SpringBoot 控制器的动态注册与卸载
java·spring boot·后端
醇醛酸醚酮酯22 分钟前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
jioulongzi27 分钟前
记录一次莫名奇妙的跨域502(badgateway)错误
开发语言·python
我是一只代码狗30 分钟前
springboot中使用线程池
java·spring boot·后端
hello早上好43 分钟前
JDK 代理原理
java·spring boot·spring
PanZonghui1 小时前
Centos项目部署之Java安装与配置
java·linux
向阳@向远方1 小时前
第二章 简单程序设计
开发语言·c++·算法
沉着的码农1 小时前
【设计模式】基于责任链模式的参数校验
java·spring boot·分布式
Mr_Xuhhh2 小时前
信号与槽的总结
java·开发语言·数据库·c++·qt·系统架构
纳兰青华2 小时前
bean注入的过程中,Property of ‘java.util.ArrayList‘ type cannot be injected by ‘List‘
java·开发语言·spring·list