【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 的扩展能力(如自定义初始化、资源管理),同时避免因生命周期管理不当导致的资源泄漏或状态错误。

相关推荐
w2sfot17 小时前
Passing Arguments as an Object in JavaScript
开发语言·javascript·ecmascript
郝学胜-神的一滴18 小时前
避免使用非const全局变量:C++中的最佳实践 (C++ Core Guidelines)
开发语言·c++·程序人生
我没想到原来他们都是一堆坏人18 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
搞一搞汽车电子18 小时前
S32K3平台eMIOS 应用说明
开发语言·驱动开发·笔记·单片机·嵌入式硬件·汽车
沙二原住民18 小时前
提升数据库性能的秘密武器:深入解析慢查询、连接池与Druid监控
java·数据库·oracle
Jerry&Grj18 小时前
SpringBoot埋点功能技术实现方案深度解析:架构设计、性能优化与扩展性实践
java·微服务·性能优化·springboot·架构设计·埋点技术
没有bug.的程序员18 小时前
Redis Stream:轻量级消息队列深度解析
java·数据库·chrome·redis·消息队列
总有刁民想爱朕ha19 小时前
车牌模拟生成器:Python3.8+Opencv代码实现与商业应用前景(C#、python 开发包SDK)
开发语言·python·数据挖掘
用户81607918333319 小时前
告别“魔法”:包你解决 Gradle 的下载慢问题
java
小菜全19 小时前
uniapp新增页面及跳转配置方法
开发语言·前端·javascript·vue.js·前端框架