当前位置: 首页 > news >正文

Spring Bean 生命周期的执行流程

1. Bean 定义阶段

在 Spring 应用启动时,会读取配置文件(如 XML 配置、Java 注解配置等)或者扫描带有特定注解(如 @Component@Service@Repository 等)的类,将这些 Bean 的定义信息加载到 Spring 的 BeanFactory 或 ApplicationContext 中。这些定义信息包括 Bean 的类名、作用域、依赖关系等。

2. Bean 实例化阶段

  • 调用构造函数:Spring 根据 Bean 的定义信息,使用反射机制调用 Bean 类的构造函数来创建 Bean 的实例。如果 Bean 类有多个构造函数,Spring 会根据依赖注入的规则选择合适的构造函数。
  • 示例代码
public class MyBean {
    public MyBean() {
        System.out.println("MyBean 实例化中,调用构造函数");
    }
}

3. 属性注入阶段

在 Bean 实例化完成后,Spring 会根据 Bean 的定义信息,将依赖的其他 Bean 或属性值注入到该 Bean 中。注入方式包括构造函数注入、Setter 方法注入和字段注入等。

  • 示例代码
public class MyBean {
    private AnotherBean anotherBean;

    public MyBean() {
        System.out.println("MyBean 实例化中,调用构造函数");
    }

    public void setAnotherBean(AnotherBean anotherBean) {
        this.anotherBean = anotherBean;
        System.out.println("MyBean 属性注入:注入 AnotherBean");
    }
}

public class AnotherBean {
    // ...
}

4. Bean 初始化前阶段

在属性注入完成后,Spring 会检查 Bean 是否实现了 BeanNameAwareBeanFactoryAware 或 ApplicationContextAware 接口,如果实现了这些接口,会依次调用相应的方法。

  • BeanNameAware 接口:该接口有一个 setBeanName 方法,Spring 会将 Bean 的名称传递给该方法。
  • BeanFactoryAware 接口:该接口有一个 setBeanFactory 方法,Spring 会将当前的 BeanFactory 传递给该方法。
  • ApplicationContextAware 接口:该接口有一个 setApplicationContext 方法,Spring 会将当前的 ApplicationContext 传递给该方法。
  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MyBean implements BeanNameAware, ApplicationContextAware {
    private String beanName;
    private ApplicationContext applicationContext;

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("MyBean 初始化前:设置 Bean 名称为 " + beanName);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("MyBean 初始化前:设置 ApplicationContext");
    }
}

5. Bean 初始化阶段

  • InitializingBean 接口:如果 Bean 实现了 InitializingBean 接口,Spring 会调用其 afterPropertiesSet 方法,该方法可以用于在属性注入完成后进行一些初始化操作。
  • @PostConstruct 注解:如果 Bean 的某个方法上使用了 @PostConstruct 注解,Spring 会在该方法上调用该注解标记的方法。
  • 自定义初始化方法:在 Bean 的定义中,可以通过 init-method 属性指定一个自定义的初始化方法,Spring 会在合适的时机调用该方法。
  • 示例代码
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.InitializingBean;

public class MyBean implements InitializingBean {
    @PostConstruct
    public void postConstructMethod() {
        System.out.println("MyBean 初始化:@PostConstruct 注解方法执行");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("MyBean 初始化:InitializingBean 的 afterPropertiesSet 方法执行");
    }

    public void customInitMethod() {
        System.out.println("MyBean 初始化:自定义初始化方法执行");
    }
}

6. Bean 初始化后阶段

在 Bean 初始化完成后,Spring 会检查 Bean 是否需要进行 AOP 代理,如果需要,会为 Bean 创建代理对象。同时,如果 Bean 实现了 BeanPostProcessor 接口,Spring 会调用其 postProcessAfterInitialization 方法,该方法可以对 Bean 进行一些额外的处理。

  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBean 初始化后:BeanPostProcessor 的 postProcessAfterInitialization 方法执行,处理 " + beanName);
        return bean;
    }
}

7. Bean 使用阶段

经过上述步骤,Bean 已经完成了初始化过程,可以被应用程序使用。在应用程序的运行过程中,可以通过 ApplicationContext 或 BeanFactory 获取 Bean 实例,并调用其方法。

8. Bean 销毁前阶段

当 Spring 容器关闭时,会触发 Bean 的销毁过程。在销毁之前,如果 Bean 实现了 DisposableBean 接口,Spring 会调用其 destroy 方法。

  • 示例代码
import org.springframework.beans.factory.DisposableBean;

public class MyBean implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("MyBean 销毁前:DisposableBean 的 destroy 方法执行");
    }
}

9. Bean 销毁阶段

  • @PreDestroy 注解:如果 Bean 的某个方法上使用了 @PreDestroy 注解,Spring 会在该方法上调用该注解标记的方法。
  • 自定义销毁方法:在 Bean 的定义中,可以通过 destroy-method 属性指定一个自定义的销毁方法,Spring 会在容器关闭时调用该方法。
  • 示例代码
import javax.annotation.PreDestroy;

public class MyBean {
    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("MyBean 销毁:@PreDestroy 注解方法执行");
    }

    public void customDestroyMethod() {
        System.out.println("MyBean 销毁:自定义销毁方法执行");
    }
}

总结

Spring Bean 的生命周期可以概括为:定义 -> 实例化 -> 属性注入 -> 初始化前 -> 初始化 -> 初始化后 -> 使用 -> 销毁前 -> 销毁。通过实现不同的接口和使用注解,我们可以在 Bean 的生命周期的不同阶段进行定制化处理。

相关文章:

  • ES12 weakRefs的用法和使用场景
  • frameworks 之 Activity添加View
  • Canal 部署binlog 监听
  • 【MySQL】环境变量配置
  • Linux 命令
  • 汽车长期不保养的危害
  • 【鸿蒙Next】鸿蒙应用发布前的准备
  • 泰山派RK3566移植QT,动鼠标时出现屏幕闪烁
  • 微信支付V3平台证书切换成公钥遇到的问题。【无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥】【 Illegal base64 character 2d】
  • 【CCF CSP-J 2023】一元二次方程
  • U-Net 与深度学习的完美结合:图像分割的高效解决方案
  • Windows 环境下配置多个不同版本的 Maven
  • Vue3+Vite创造路由
  • Kubernetes的Ingress 资源是什么?
  • 【综合实验】
  • docker修改镜像默认存储路径(基于页面迁移)
  • 跟着 Lua 5.1 官方参考文档学习 Lua (2)
  • 【HarmonyOS NEXT】获取正式应用签名证书的签名信息
  • 基于 Spring Boot + 微信小程序的短文写作竞赛管理系统设计与实现(源码+文档)
  • 《Python在数据可视化中的应用与实践》
  • 国际观察|韩国在政局多重不确定性中迎接总统选举
  • 陈逸飞《黄河颂》人物造型与借鉴影像意义
  • 生命与大海相连:他在300多米的深海行走,在沉船一线打捞救援
  • 《大风杀》上海首映,白客说拍这戏是从影以来的最大挑战
  • 五一去哪玩?“时代交响”音乐会解锁艺术假期
  • 全国人大常委会关于授权国务院在中国(新疆)自由贸易试验区暂时调整适用《中华人民共和国种子法》有关规定的决定