首页 > 其他分享 >Spring Bean的生命周期流程

Spring Bean的生命周期流程

时间:2024-03-16 10:32:52浏览次数:19  
标签:初始化 生命周期 Spring Bean 执行 方法 public

前言

Java 中的公共类称之为Java Bean,而 Spring 中的 Bean 指的是将对象的生命周期,交给Spring IoC 容器来管理的对象。所以 Spring 中的 Bean 对象在使用时,无需通过 new 来创建对象,只需要通过 DI(依赖注入),从 Spring 中取出要使用的对象即可。

在Spring框架中单实例Bean的初始化和销毁过程有这样的执行顺序:

初始化顺序:@PostConstruct → InitializingBean → init-method
销毁顺序:@PreDestroy → DisposableBean → destroy-method

在初始化Bean时,@PostConstruct注解方法会首先被执行,然后是实现InitializingBean接口的afterPropertiesSet方法,最后是init-method指定的方法。

在销毁Bean时,@PreDestroy注解方法会首先被执行,然后是实现DisposableBean接口的destroy方法,最后是destroy-method指定的方法。

简单总结一下Spring Bean生命周期的流程:

  1. 实例化(通过构造器方法);
  2. 设置Bean的属性(通过setter方法);
  3. 调用Bean的初始化方法(@PostConstruct、afterPropertiesSet方法或者init-method指定的方法);
  4. Bean可以被应用程序使用;
  5. 当容器关闭时,调用Bean的销毁方法(@PreDestroy、destroy方法或者destroy-method指定的方法)。
1.Bean生命周期

Spring 中 Bean 的生命周期是指:Bean 在 Spring(IoC)中从创建到销毁的整个过程。

 Spring 中 Bean 的生命周期主要包含以下 5 部分:

  • 实例化:为 Bean 分配内存空间;
  • 设置属性:将当前类依赖的 Bean 属性,进行注入和装配;
  • 初始化:
    • 执行各种通知;
    • 执行初始化的前置方法;
    • 执行初始化方法;
    • 执行初始化的后置方法。
  • 使用 Bean:在程序中使用 Bean 对象;
  • 销毁 Bean:将 Bean 对象进行销毁操作。

需要注意的是:“实例化”和“初始化”是两个完全不同的过程,千万不要搞混;实例化只是给 Bean 分配了内存空间,而初始化则是将程序的执行权,从系统级别转换到用户级别,并开始执行用户添加的业务代码

2.代码演示

因为 Spring Boot 是基于 Spring 创建的,所以 Bean 在 Spring 或 Spring Boot 中的行为都是一致的;接下来我们使用代码的方式在 Spring Boot 中,演示一下 Bean 的生命周期。

  • 首先,我们创建一个 Bean 对象,起名为 BeanLifecycleComponent,名称可以自己指定
@Component
public class BeanLifecycleComponent implements BeanNameAware {
    public void setBeanName(String s) {
        System.out.println("执行 BeanName 的通知方法");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("执行初始化方法");
    }

    public void use() {
        System.out.println("使用 Bean");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("执行销毁的方法");
    }
}
  • 然后我们创建一个 MyBeanPostProcessor 类,实现初始化的前置方法和初始化的后置方法
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanLifecycleComponent")) {
            System.out.println("执行初始化前置方法...");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanLifecycleComponent")) {
            System.out.println("执行初始化后置方法...");
        }
        return bean;
    }
}

注意:初始化的前置方法和后置方法是为所有 Bean 服务的,而非为某一个 Bean 服务的,所以这两个方法不能写在某个具体的 Bean 中,要创建一个单独的类来执行,否则(这两个方法)不会执行。

  • 最后,在 Spring Boot 的启动类中获取 Bean
@SpringBootApplication
public class SpringbootDay01Application {

    public static void main(String[] args) {
        //加载上下文环境
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootDay01Application.class, args);
        // 获取Bean
        BeanLifecycleComponent component = context.getBean(BeanLifecycleComponent.class);
        // 使用Bean
        component.use();
        // 停止Spring Boot服务
        context.close();

    }

}

上面程序的执行结果输出:

问题:能不能先执行初始化再执行设置属性呢?也就是将生命周期中的步骤 2 和步骤 3 的执行顺序交换一下? 答案是否定的。

比如以下代码的执行:

@Controller
public class UserController {
    @Resource
    private UserService userService;

    @PostConstruct // 初始化方法
    public void postConstruct() {
        userService.sayHello();
    }
}

此时如果先执行步骤 2,先将 UserService 注入到当前类,再调用步骤 3 执行初始化,那么程序的执行是正常的。如果将交换步骤 2 和步骤 3 的执行顺序,那么程序执行就会报错(空指针异常),所以 Bean 的生命周期顺序必须是上面的顺序。

标签:初始化,生命周期,Spring,Bean,执行,方法,public
From: https://blog.csdn.net/A_aspectJ/article/details/136700597

相关文章

  • Spring框架与其他框架(如Struts、Hibernate等)相比有何独特之处?Spring框架的主要优点有
    Spring框架与其他框架(如Struts、Hibernate等)相比有何独特之处?在Spring框架的面试中,可能会被问到的问题涵盖多个方面,包括但不限于以下几个方面:Spring框架的基本理解:请简述一下你对Spring框架的理解。Spring框架的主要优点有哪些?Spring框架与其他框架(如Struts、Hibernate......
  • 解释一下Spring中的IoC(控制反转)和DI(依赖注入)是什么,它们之间有何关系?Spring的Bean的生
    解释一下Spring中的IoC(控制反转)和DI(依赖注入)是什么,它们之间有何关系?在Spring框架中,IoC(控制反转)和DI(依赖注入)是两个核心概念,它们对于实现松耦合和高度可配置的应用程序至关重要。IoC(控制反转):IoC,即控制反转,是一种设计思想,其核心思想是将原本由代码直接操控的对象的调用权交......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程一
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程二
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • Springboot
    SpringBootSpringBoot集成PageHelper加入依赖<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version></dependency>写代码/......
  • springboot仓库管理系统(附:源码+课件)
    项目介绍:管理员system123456客户表(ID客户名称邮编客户地址客户电话联系人联系人电话开户行账号邮箱)供应商表(ID供应商名称邮编供应商地址供应商电话联系人联系人电话开户行账号邮箱)商品表(ID商品名称供应商产地商品规格商品包装生产批号批准文号商......
  • 智慧医养大数据公共服务系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍随着老龄化社会的到来和大数据技术的发展,智慧医养结合的公共服务系统成为社会关注的热点。这一系统能够集成医疗、养老、健康管理等数据,通过智能分析和处理,......
  • SpringBoot鲜花商城管理系统Java
    一 设计背景1.1课题现状1.2课题意义二 开发环境及技术架构22.1开发环境与工具2.2技术架构三 需求分析3.1系统目标3.2功能需求3.3性能要求四 系统设计4.1系统功能总体设计4.2系统详细设计4.2.1用户登录4.2.2用户注册4.2.3管理员登......
  • springboot235基于SpringBoot的房屋交易平台的设计与实现
          本科毕业设计论文题目:房屋交易平台设计与实现系   别:XX系(全称)专    业:软件工程班   级:软件工程15201学生姓名:学生学号:指导教师:导师1       导师2摘  要信息数据从传统到当代,是一直在变革当中,突如其......
  • springboot233大学生就业需求分析系统
          本科毕业设计论文题目:大学生就业需求分析系统设计与实现系   别:XX系(全称)专    业:软件工程班   级:软件工程15201学生姓名:学生学号:指导教师:导师1       导师2摘  要信息数据从传统到当代,是一直在变革......