news 2026/4/16 17:57:18

(18)Bean的生命周期

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(18)Bean的生命周期

什么是Bean的生命周期

Spring其实就是一个管理Bean对象的工厂。它负责对象的创建,对象的销毁等。
所谓的生命周期就是:对象从创建开始到最终销毁的整个过程。
什么时候创建Bean对象?
创建Bean对象的前后会调用什么方法?
Bean对象什么时候销毁?
Bean对象的销毁前后调用什么方法?

为什么要知道Bean的生命周期

其实生命周期的本质是:在哪个时间节点上调用了哪个类的哪个方法。
我们需要充分的了解在这个生命线上,都有哪些特殊的时间节点。
只有我们知道了特殊的时间节点都在哪,到时我们才可以确定代码写到哪。
我们可能需要在某个特殊的时间点上执行一段特定的代码,这段代码就可以放到这个节点上。当生命线走到这里的时候,自然会被调用。

Bean的生命周期之5步(简略版生命周期(必须掌握))

相比5步多出来的是哪2步?
在初始化Bean的前和后

Bean生命周期的管理,可以参考Spring的源码:AbstractAutowireCapableBeanFactory类的doCreateBean()方法。
Bean生命周期可以粗略的划分为五大步:

  • 第一步:创建Bean
  • 第二步:Bean属性赋值
  • 第三步:初始化Bean
  • 第四步:使用Bean
  • 第五步:销毁Bean
  • 编写测试程序:
    定义一个Bean
packagecom.powernode.spring6.bean;/** * @author 动力节点 * @version 1.0 * @className User * @since 1.0 **/publicclassUser{privateStringname;publicUser(){System.out.println("1.实例化Bean");}publicvoidsetName(Stringname){this.name=name;System.out.println("2.Bean属性赋值");}publicvoidinitBean(){System.out.println("3.初始化Bean");}publicvoiddestroyBean(){System.out.println("5.销毁Bean");}}
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- init-method属性指定初始化方法。 destroy-method属性指定销毁方法。 --><beanid="userBean"class="com.powernode.spring6.bean.User"init-method="initBean"destroy-method="destroyBean"><propertyname="name"value="zhangsan"/></bean></beans>
packagecom.powernode.spring6.test;importcom.powernode.spring6.bean.User;importorg.junit.Test;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;/** * @author 动力节点 * @version 1.0 * @className BeanLifecycleTest * @since 1.0 **/publicclassBeanLifecycleTest{@TestpublicvoidtestLifecycle(){ApplicationContextapplicationContext=newClassPathXmlApplicationContext("spring.xml");UseruserBean=applicationContext.getBean("userBean",User.class);System.out.println("4.使用Bean");// 只有正常关闭spring容器才会执行销毁方法ClassPathXmlApplicationContextcontext=(ClassPathXmlApplicationContext)applicationContext;context.close();}}

需要注意的:

  • 第一:只有正常关闭spring容器,bean的销毁方法才会被调用。
  • 第二:ClassPathXmlApplicationContext类才有close()方法。
  • 第三:配置文件中的init-method指定初始化方法。destroy-method指定销毁方法。

8.4 Bean生命周期之7步

在以上的5步中,第3步是初始化Bean,如果你还想在初始化前和初始化后添加代码,可以加入“Bean后处理器”。
编写一个类实现BeanPostProcessor类,并且重写before和after方法:

packagecom.powernode.spring6.bean;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.config.BeanPostProcessor;/** * @author 动力节点 * @version 1.0 * @className LogBeanPostProcessor * @since 1.0 **/publicclassLogBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("Bean后处理器的before方法执行,即将开始初始化");returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("Bean后处理器的after方法执行,已完成初始化");returnbean;}}

在spring.xml文件中配置“Bean后处理器”:

<!--配置Bean后处理器。这个后处理器将作用于当前配置文件中所有的bean。--><beanclass="com.powernode.spring6.bean.LogBeanPostProcessor"/>

一定要注意:在spring.xml文件中配置的Bean后处理器将作用于当前配置文件中所有的Bean。
执行测试程序:
如果加上Bean后处理器的话,Bean的生命周期就是7步了。

Bean生命周期之10步(十分详细生命周期(尽量掌握))

如果根据源码跟踪,可以划分更细粒度的步骤,10步:

相比7步多出来的是哪三步?

  • 点位1:在Bean后处理器before方法之前

  • 点位2:在Bean后处理器before方法之后

  • 点位3:使用Bean后,或者说销毁Bean之前
    添加的这三个点位的特点,都是在检查你这个Bean是否实现了某些特定的接口,如果实现了这些接口,则spring容器会调用这个接口中的方法
    它们干了什么?

  • 点位1:检查Bean是否实现了Aware的相关接口,Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

    • 当Bean实现了BeanNameAware,Spring会将Bean的名字传递给Bean。
    • 当Bean实现了BeanClassLoaderAware,Spring会将加载该Bean的类加载器传递给Bean。
    • 当Bean实现了BeanFactoryAware,Spring会将Bean工厂对象传递给Bean。
  • 点位2:检查Bean是否实现了InitializingBean,如果实现了,则调用接口的方法

  • 点位3:检查Bean是否实现了DisposableBean,如果实现了,则调用接口的方法
    测试以上10步,可以让User类实现5个接口,并实现所有方法:

  • BeanNameAware

  • BeanClassLoaderAware

  • BeanFactoryAware

  • InitializingBean

  • DisposableBean

代码如下:

packagecom.powernode.spring6.bean;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.*;/** * @author 动力节点 * @version 1.0 * @className User * @since 1.0 **/publicclassUserimplementsBeanNameAware,BeanClassLoaderAware,BeanFactoryAware,InitializingBean,DisposableBean{privateStringname;publicUser(){System.out.println("1.实例化Bean");}publicvoidsetName(Stringname){this.name=name;System.out.println("2.Bean属性赋值");}publicvoidinitBean(){System.out.println("6.初始化Bean");}publicvoiddestroyBean(){System.out.println("10.销毁Bean");}@OverridepublicvoidsetBeanClassLoader(ClassLoaderclassLoader){System.out.println("3.类加载器:"+classLoader);}@OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{System.out.println("3.Bean工厂:"+beanFactory);}@OverridepublicvoidsetBeanName(Stringname){System.out.println("3.bean名字:"+name);}@Overridepublicvoiddestroy()throwsException{System.out.println("9.DisposableBean destroy");}@OverridepublicvoidafterPropertiesSet()throwsException{System.out.println("5.afterPropertiesSet执行");}}
packagecom.powernode.spring6.bean;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.config.BeanPostProcessor;/** * @author 动力节点 * @version 1.0 * @className LogBeanPostProcessor * @since 1.0 **/publicclassLogBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("4.Bean后处理器的before方法执行,即将开始初始化");returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("7.Bean后处理器的after方法执行,已完成初始化");returnbean;}}

通过测试可以看出来:

  • InitializingBean的方法早于init-method的执行。
  • DisposableBean的方法早于destroy-method的执行。

对于SpringBean的生命周期,掌握之前的7步即可。够用。

Bean的作用域不同,管理方式不同

Spring 根据Bean的作用域来选择管理方式。

  • 对于singleton作用域的Bean,Spring 能够精确地知道该Bean何时被创建,何时初始化完成,以及何时被销毁,所以spring可以对它进行完整的生命周期的管理;
  • 而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。
  • 我们把之前User类的spring.xml文件中的配置scope设置为prototype:
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- init-method属性指定初始化方法。 destroy-method属性指定销毁方法。 --><beanid="userBean"class="com.powernode.spring6.bean.User"init-method="initBean"destroy-method="destroyBean"scope="prototype"><propertyname="name"value="zhangsan"/></bean><!--配置Bean后处理器。这个后处理器将作用于当前配置文件中所有的bean。--><beanclass="com.powernode.spring6.bean.LogBeanPostProcessor"/></beans>

通过测试一目了然。只执行了前8步,到交给客户端使用后就不管理了,第9和10都没有执行,即检查接口和销毁Bean它都不管了

自己new的对象如何让Spring管理

有些时候可能会遇到这样的需求,某个java对象是我们自己new的,然后我们希望这个对象被Spring容器管理,怎么实现?

packagecom.powernode.spring6.bean;/** * @author 动力节点 * @version 1.0 * @className User * @since 1.0 **/publicclassUser{}
packagecom.powernode.spring6.test;importcom.powernode.spring6.bean.User;importorg.junit.Test;importorg.springframework.beans.factory.support.DefaultListableBeanFactory;/** * @author 动力节点 * @version 1.0 * @className RegisterBeanTest * @since 1.0 **/publicclassRegisterBeanTest{@TestpublicvoidtestBeanRegister(){// 自己new的对象Useruser=newUser();System.out.println(user);// 创建 默认可列表BeanFactory 对象DefaultListableBeanFactoryfactory=newDefaultListableBeanFactory();// 注册Beanfactory.registerSingleton("userBean",user);// 从spring容器中获取beanUseruserBean=factory.getBean("userBean",User.class);System.out.println(userBean);}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:59:25

2000-2024年上市公司“低空经济”概念数据

低空经济&#xff0c;是以各种有人驾驶和无人驾驶航空器的各类低空飞行活动为牵引&#xff0c;辐射带动相关领域融合发展的综合性经济形态。2021年2月&#xff0c;中共中央、 国务院在 《国家综合立体交通网规划纲要》 中首次提出发展低空经济2023年12月&#xff0c;中央经济工…

作者头像 李华
网站建设 2026/4/16 10:59:05

如何为特定应用选型滚珠导轨?

滚珠导轨在工业机械设备中是关键的传动元件&#xff0c;广泛应用于数控机床、自动化设备、精密仪器等领域。固在机械设备中选择适合的滚珠导轨直接决定了设备的性能稳定性与最终品质。面对特定应用场景&#xff0c;如何选择适合的滚珠导轨&#xff0c;是个关键的问题。确定负载…

作者头像 李华
网站建设 2026/4/16 10:57:30

非冯·诺依曼原理与架构计算机深度研究报告

非冯诺依曼原理与架构计算机深度研究报告摘要&#xff1a;冯诺依曼架构自1945年提出以来&#xff0c;以“存储程序、指令与数据同源存储”的核心特征主导了现代计算机发展近百年。然而&#xff0c;随着大数据、人工智能、量子计算等领域的爆发式增长&#xff0c;该架构面临的“…

作者头像 李华
网站建设 2026/4/16 17:25:35

Swagger Core实战指南:构建企业级API文档自动生成系统

Swagger Core实战指南&#xff1a;构建企业级API文档自动生成系统 【免费下载链接】swagger-core Examples and server integrations for generating the Swagger API Specification, which enables easy access to your REST API 项目地址: https://gitcode.com/gh_mirrors/…

作者头像 李华