Spring之Bean的生命周期详解

article/2025/8/24 3:16:19

在这里插入图片描述

  通过前面多个接口的介绍了解了Bean对象生命周期相关的方法,本文就将这些接口的方法串起来,来了解Bean的完整的生命周期。而介绍Bean的生命周期也是面试过程中经常会碰到的一个问题,如果不注意就跳坑里啦~~


Spring之Bean对象的初始化和销毁方法
Spring之InitializingBean接口和DisposableBean接口介绍
Spring之Aware接口介绍
Spring之InstantiationAwareBeanPostProcessor接口介绍
Spring之BeanFactoryPostProcessor接口介绍
Spring之BeanPostProcessor(后置处理器)介绍


建议:看此文前请将上面相关的内容熟悉下,便于理解下面的内容。

文章目录

  • Bean生命周期
    • 一、调用过程
    • 二、生命周期方法说明
    • 三、演示
      • 1.BeanFactoryPostProcessor接口
      • 2.BeanPostProcessor接口
      • 3.InstantiationAwareBeanPostProcessor接口
      • 4.BeanNameAware,BeanFactoryAware等Aware接口
      • 5.InitializingBean,DisposableBean接口
      • 6.@PostConstruct和@PreDestroy注解
      • 7.init-method,destroy-method
      • 8.测试
    • 四、Bean对象生命周期总结

Bean生命周期

一、调用过程

在这里插入图片描述

二、生命周期方法说明

接口方法说明
BeanFactoryPostProcessorpostProcessBeanFactory在Bean对象实例化之前执行, 通过beanFactory可以获取bean的定义信息, 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
BeanPostProcessorpostProcessBeforeInitialization实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
postProcessAfterInitialization实例化、依赖注入、初始化完毕时执行
InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation在方法实例化之前执行,返回结果为null正常执行,返回结果如果不为null则会跳过相关方法而进入初始化完成后的流程
postProcessAfterInstantiation在方法实例化之后执行,返回结果true才会执行postProcessPropertyValues方法
postProcessPropertyValues可以用来修改Bean中属性的内容
InitializingBeanafterPropertiesSet初始化的方法
DisposableBeandestroy容器销毁前的回调方法
AwaresetXXX感知对应Spring容器的内容
@PostConstruct标注在方法头部,表示初始化的方法
@PreDestroy标注在方法头部,表示销毁前回调的方法
init-method属性指定初始化的方法
destory-method属性指定销毁前的回调方法

三、演示

1.BeanFactoryPostProcessor接口

  该接口中的方法是最先执行的。在Bean实例化之前执行

/*** 自定义BeanFactoryPostProcessor* * @author dengp**/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {/*** 本方法在Bean对象实例化之前执行,* 通过beanFactory可以获取bean的定义信息,* 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("****** BeanFactoryPostProcessor 开始执行了");/*String[] names = beanFactory.getBeanDefinitionNames();for (String name : names) {if("user".equals(name)){BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();// MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息if(propertyValues.contains("name")){propertyValues.addPropertyValue("name", "bobo");System.out.println("修改了属性信息");}}}*/System.out.println("******* BeanFactoryPostProcessor 执行结束了");}
}

2.BeanPostProcessor接口

  该接口中定义了两个方法,分别在Bean对象实例化及装配后在初始化的前后执行

/*** 自定义BeanPostProcessor实现类* BeanPostProcessor接口的作用是:* 	 我们可以通过该接口中的方法在bean实例化、配置以及其他初始化方法前后添加一些我们自己的逻辑* @author dengp**/
public class MyBeanPostProcessor implements BeanPostProcessor{/*** 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务* 注意:方法返回值不能为null* 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象* 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if("user".equals(beanName)){System.out.println(">>后置处理器 before方法:"+bean+"\t"+beanName);}// 可以根据beanName不同执行不同的处理操作return bean;}/*** 实例化、依赖注入、初始化完毕时执行 * 注意:方法返回值不能为null* 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象* 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if("user".equals(beanName)){System.out.println("<<后置处理器after方法:"+bean+"\t"+beanName);}// 可以根据beanName不同执行不同的处理操作return bean;}
}

3.InstantiationAwareBeanPostProcessor接口

  该接口是BeanPostProcessor接口的子接口,所以该接口肯定具有BeanPostProcessor接口的功能,同时又定义了三个自己的接口,这三个接口是在Bean实例化前后执行的方法。

/*** 自定义处理器* @author dengp**/
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor{/*** BeanPostProcessor接口中的方法* 在Bean的自定义初始化方法之前执行* Bean对象已经存在了*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubif("user".equals(beanName)){System.out.println("【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization");}return bean;}/*** BeanPostProcessor接口中的方法* 在Bean的自定义初始化方法执行完成之后执行* Bean对象已经存在了*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if("user".equals(beanName)){System.out.println("【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization");}return bean;}/*** InstantiationAwareBeanPostProcessor中自定义的方法* 在方法实例化之前执行  Bean对象还没有*/@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {if("user".equals(beanName)){System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation");}return null;}/*** InstantiationAwareBeanPostProcessor中自定义的方法* 在方法实例化之后执行  Bean对象已经创建出来了*/@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {if("user".equals(beanName)){System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation");}return true;}/*** InstantiationAwareBeanPostProcessor中自定义的方法* 可以用来修改Bean中属性的内容*/@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,String beanName) throws BeansException {if("user".equals(beanName)){System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues--->");}return pvs;}
}

4.BeanNameAware,BeanFactoryAware等Aware接口

  Aware接口是用来让对象感知当前的IOC环境

5.InitializingBean,DisposableBean接口

  这两个接口是Bean初始化及销毁回调的方法。

6.@PostConstruct和@PreDestroy注解

package com.dpb.pojo;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/*** 实现InitializingBean和DisposableBean接口* @author dengp**/
public class User implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware{private int id;private String name;//感知本对象在Spring容器中的id属性private String beanName;// 感知本对象所属的BeanFactory对象private BeanFactory factory;public User(){System.out.println("构造方法被执行了...User 被实例化");}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {System.out.println("《注入属性》注入name属性"+name);this.name = name;}public String getBeanName() {return beanName;}@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + ", beanName=" + beanName + "]";}/*** bean对象销毁前的回调方法*/@Overridepublic void destroy() throws Exception {// TODO Auto-generated method stubSystem.out.println("《DisposableBean接口》destory ....");}/*** 初始化的方法*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("初始化:《InitializingBean接口》afterPropertiesSet....");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {// TODO Auto-generated method stubSystem.out.println("【BeanFactoryAware接口】setBeanFactory");this.factory = beanFactory;}@Overridepublic void setBeanName(String name) {System.out.println("【BeanNameWare接口】setBeanName");this.beanName = name;}public BeanFactory getFactory() {return factory;}/*** 也是个初始化的方法*/@PostConstructpublic void postConstruct(){System.out.println("初始化:【@PostConstruct】执行了...");}/*** 销毁前的回调方法*/@PreDestroypublic void preDestory(){System.out.println("【@preDestory】执行了...");} /*** 初始化的方法* 通过bean标签中的 init-method属性指定*/public void start(){System.out.println("初始化:【init-method】方法执行了....");}/*** 销毁前的回调方法* 通过bean标签中的 destory-method属性指定*/public void stop(){System.out.println("【destory-method】方法执行了....");}
}

7.init-method,destroy-method

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"><context:annotation-config/><bean class="com.dpb.pojo.User" id="user" init-method="start" destroy-method="stop" ><property name="name" value="波波烤鸭"></property></bean><!-- 注册后置处理器 --><bean class="com.dpb.processor.MyBeanPostProcessor"/><!-- 注册 InstantiationAwareBeanPostProcessor --><bean class="com.dpb.processor.MyInstantiationAwareBeanPostProcessor"></bean><!-- 注册 BeanFactoryPostProcessor对象--><bean class="com.dpb.factoryprocessor.MyBeanFactoryPostProcessor"/>
</beans>

8.测试

@Test
public void test1() {System.out.println("Spring容器开始加载....");ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");User user = ac.getBean(User.class);System.out.println("---------------"+user);ac.registerShutdownHook();System.out.println("Spring容器卸载完成....");
}

输出结果

Spring容器开始加载....
三月 04, 2019 11:14:38 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy
三月 04, 2019 11:14:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
****** BeanFactoryPostProcessor 开始执行了
******* BeanFactoryPostProcessor 执行结束了
【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation
构造方法被执行了...User 被实例化
【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation
【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues--->
《注入属性》注入name属性波波烤鸭
【BeanNameWare接口】setBeanName
【BeanFactoryAware接口】setBeanFactory
>>后置处理器 before方法:User [id=0, name=波波烤鸭, beanName=user]	user
【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization
初始化:【@PostConstruct】执行了...
初始化:《InitializingBean接口》afterPropertiesSet....
初始化:【init-method】方法执行了....
<<后置处理器after方法:User [id=0, name=波波烤鸭, beanName=user]	user
【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization
---------------User [id=0, name=波波烤鸭, beanName=user]
Spring容器卸载完成....
三月 04, 2019 11:14:39 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy
【@preDestory】执行了...
《DisposableBean接口》destroy ....
【destory-method】方法执行了....

四、Bean对象生命周期总结

  1. 如果实现了BeanFactoryPostProcessor接口,那么在容器启动的时候,该接口中的postProcessBeanFactory方法可以修改Bean中元数据中的信息。该方法是在实例化对象之前执行
  2. 如果实现了InstantiationAwareBeanPostProcessor接口,那么在实例化Bean对象之前会调用postProcessBeforeInstantiation方法,该方法如果返回的不为null则会直接调用postProcessAfterInitialization方法,而跳过了Bean实例化后及初始化前的相关方法,如果返回null则正常流程,postProcessAfterInstantiation在实例化成功后执行,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true, postProcessPropertyValues就会被执行,postProcessPropertyValues用来修改属性,在初始化方法之前执行。
  3. 如果实现了Aware相关的结果,那么相关的set方法会在初始化之前执行。
  4. 如果实现了BeanPostProcessor接口,那么该接口的方法会在实例化后的初始化方法前后执行。
  5. 如果实现了InitializingBean接口则在初始化的时候执行afterPropertiesSet
  6. 如果指定了init-method属性则在初始化的时候会执行指定的方法。
  7. 如果指定了@PostConstruct则在初始化的时候会执行标注的方法。
  8. 到此对象创建完成
  9. 当对象需要销毁的时候。
  10. 如果实现了DisposableBean接口会执行destroy方法
  11. 如果指定了destroy-method属性则会执行指定的方法
  12. 如果指定了@PreDestroy注解则会执行标注的方法

~ 这就是Bean对象的生命周期了。有问题的欢迎留言


http://chatgpt.dhexx.cn/article/FovTo5MV.shtml

相关文章

Bean的生命周期及演示

文章目录 一、介绍概念Bean生命周期组成&#xff1a; 二、实例演示 一、介绍 概念 Bean的生命周期是指一个Bean对象从创建到销毁的整个存在过程。 Bean生命周期组成&#xff1a; 1.实例化Bean&#xff08;为Bean分配内存空间&#xff09; 2.属性注入 (Bean注入和装配) 3.Bean…

面试题:Spring Bean的生命周期

最近在复习Spring的面试题&#xff0c;关于Spring Bean的生命周期一直没有很深入的理解&#xff0c;自己结合源码参考了网上的几篇文章&#xff0c;写了一点东西&#xff0c;方便理解。 Spring 启动&#xff0c;查找并加载需要被 Spring 管理的 Bean&#xff0c;进行 Bean 的…

Bean的生命周期和作用域

Bean的生命周期 Bean的执行流程&#xff1a; Bean 执行流程&#xff1a;启动Spring 容器 -> 实例化 Bean&#xff08;分配内存空间&#xff0c;从无到有&#xff09;-> Bean 注册到 Spring 中&#xff08;存操作&#xff09; -> 将 Bean 装配到需要的类中&#xff08;…

关于Spring Bean的生命周期

一、简介 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置&#xff0c;从BeanFactory或ApplicationContext取得的实例为Singleton&#xff0c;也就是预设为每一个Bean的别名只能维持一个实例&#xff0c;而不是每次都产生一个新的对象使用Singleton模式产生单一实…

7、Bean的生命周期

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

【一篇搞懂】 bean的生命周期详解

概述 Spring中的一个Bean从生到灭要经历很多过程,总体分为Bean定义、实例化、属性赋值(依赖注入)、初始化、生存期、销毁几个阶段: ​​​​​​​​ 下面是一个细化的Bean生命周期图: 过程比较复杂,重点关注Bean的定义、初始化、销毁过程,可以抓住重点: BeanPostPro…

Bean 生命周期详解

Spring Bean 的生命周期&#xff0c;面试时非常容易问&#xff0c;这不&#xff0c;前段时间就有个粉丝去字节面试&#xff0c;因为不会回答这个问题&#xff0c;一面都没有过。 如果只讲基础知识&#xff0c;感觉和网上大多数文章没有区别&#xff0c;但是我又想写得稍微深入…

【Spring】Spring的Bean的生命周期

作者简介&#xff1a;大家好&#xff0c;我是五度鱼&#xff0c;一个普通的Java领域博主&#xff0c;不停输出Java技术博客和干货。座右铭&#xff1a;锲而不舍&#xff0c;金石可镂。个人主页&#xff1a;五度鱼学Java的主页 文章目录 前言1. 什么是Bean的生命周期&#xff1f…

Spring中bean的生命周期(最详细)

Spring Bean的生命周期是Spring面试热点问题。Spring Bean的生命周期指的是从一个普通的Java类变成Bean的过程&#xff0c;深知Spring源码的人都知道这个给面试官讲的话大可讲30分钟以上&#xff0c;如果你不没有学习过Spring的源码&#xff0c;可能就知道Aware接口和调用init方…

Bean的生命周期

目录 一&#xff0c;bean的初始化 &#xff08;1&#xff09;Spring的IOC和AOP&#xff1a; &#xff08;2&#xff09;Spring Bean的生命周期&#xff1a; 二&#xff0c;单例模式与多例模式的区别 区别 《代码演示》 前言 回顾&#xff1a;Servlet的生命 初始化&#x…

bean的生命周期(最全最细讲解)

一、bean生命周期&#xff1a; 其定义为&#xff1a;从对象的创建到销毁的过程。而Spring中的一个Bean从开始到结束经历很多过程&#xff0c;但总体可以分为六个阶段Bean定义、实例化、属性赋值、初始化、生存期、销毁。 二、案例代码演示 1.首先我们来创建一个包&#xff0…

去字节面试,直接让人出门左拐:Bean 生命周期都不知道!

Spring Bean 的生命周期&#xff0c;面试时非常容易问&#xff0c;这不&#xff0c;前段时间就有个粉丝去字节面试&#xff0c;因为不会回答这个问题&#xff0c;一面都没有过。 如果只讲基础知识&#xff0c;感觉和网上大多数文章没有区别&#xff0c;但是我又想写得稍微深入…

Spring Bean生命周期,好像人的一生。。

大家好&#xff0c;我是老三&#xff0c;上节我们手撸了一个简单的IOC容器五分钟&#xff0c;手撸一个Spring容器&#xff01;&#xff0c;这节我们来看一看Spring中Bean的生命周期&#xff0c;我发现&#xff0c;和人的一生真的很像。 简单说说IoC和Bean IoC&#xff0c;控制…

Spring中bean的生命周期

Spring中的bean的生命周期主要包含四个阶段&#xff1a;实例化Bean --&#xff1e; Bean属性填充 --&#xff1e; 初始化Bean --&#xff1e;销毁Bean 首先是实例化Bean&#xff0c;当客户向容器请求一个尚未初始化的bean时&#xff0c;或初始化bean的时候需要注入另一个尚末初…

一文读懂 Spring Bean 的生命周期

欢迎大家关注我的微信公众号【老周聊架构】&#xff0c;Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。 一、前言 今天我们来说一说 Spring Bean 的生命周期&#xff0c;小伙伴们应该在面试中经常遇到&#xff0c;这是正常现象。…

ubuntu 换源深层次解析

换源也是一个容易出错的问题&#xff0c;本文以树莓派为例展开&#xff0c;x86也是一样的操作。 那么假设成立的话&#xff0c;就要记住我们是在树莓派&#xff08;arm&#xff09;上安装的ubuntu&#xff0c;不是X86&#xff0c;不是amd。 安装好系统后&#xff0c;我们第一…

[Linux]Ubuntu 换源 20.04 阿里源

注意&#xff0c;这篇文章其实不是简单的教你怎么换源&#xff0c;而是示例一种方法来换20.04的阿里源&#xff0c;其他源和版本大同小异。 笔者在写这篇文章的时候&#xff0c;20.04 还没有release出来正式版&#xff0c;但是已经可以在仓库里看到有源存在了&#xff0c;故写下…

Ubuntu换源详解,教你如何换源,并且解决常见的大坑

Ubuntu换源详解&#xff0c;教你如何换源&#xff0c;并且解决常见的大坑 记一次极不愉快的一次经历 首先注意&#xff0c;换源必须选择合适的版本&#xff0c;不可以在网上找一个下载源就直接去换 出现错误1&#xff1a; 由于没有公钥&#xff0c;无法验证下列签名 :NO_PUBK…

ubuntu 换源

网上应该可以找到很多关于ubuntu源的设置方法&#xff0c;但是如果不搞清楚就随便设置的话&#xff0c;不仅不能起到应有的效果&#xff0c;还会由于一些问题导致apt不可用。 最正确的更换源的方法应该如系统提示的&#xff1a; ## a.) add apt_preserve_sources_list: true …

20.04Ubuntu换源:提升软件下载速度和更新效率

在使用Ubuntu操作系统时&#xff0c;一个常见的优化措施是更改软件源&#xff0c;以提高软件下载速度和更新效率。软件源是指存储软件包的服务器&#xff0c;通过更换软件源&#xff0c;你可以选择更靠近你所在地区的服务器&#xff0c;从而加快软件下载速度&#xff0c;并减少…