Spring如何管理Bean的生命周期呢?

我们都知道,在面试的过程中,关于 Spring 的面试题,那是各种各样,很多时候就会问到关于 Spring的相关问题,比如 AOP ,IOC 等等,还有就是关于 Spring 是如何管理 Bean 的生命周期的相关问题,今天了不起就来和大家一起看看 Spring 是如何管理 Bean 的生命周期的。

源码分析

BeanFactory

其实我们对于这个 Spring 管理 Bean 的生命周期有时候并不需要我们去大篇幅的去背诵某块的内容,我们需要的就是学会看源代码,比如源代码中的注释部分,当我们看到这注释部分的时候,很大程度上能够帮助我们理解源码的含义。

BeanFactory是Spring框架中的一个接口,它是一个工厂类,用来创建和管理Spring中的Bean对象。

我们看源码中的注释

* <p>Bean factory implementations should support the standard bean lifecycle interfaces* as far as possible. The full set of initialization methods and their standard order is:

这句话直接翻译就是 Bean Factory 实现类应该尽可能的支持标准的生命周期接口。注释的下半段内容,就是描述的 Bean 生命周期的相关内容了。所以源码里面的注释需要我们及时的去看一下,虽然都是纯英文的,但是能读出个大概得内容,再去看源码的话,至少知道它是干嘛的方法。

Bean 的生命周期

我们在了解他如何管理的时候,我们得先知道这个 Bean 的生命周期都有哪几个阶段,知道了阶段,我们再来看它的实现。

我们先总结:

Bean 的生命周期可以总结为如下的几个阶段,

1. Bean的实例化阶段

2. Bean的设置属性阶段

3. Bean的 初始化阶段

4. Bean的销毁阶段

也有些人会细分实例化阶段,就是把实例化拆分成两部分,第一部分是注册阶段,第二部分是实例化阶段,其实区别不大。

Bean实例化阶段

在Spring框架中,Bean的实例化是一个核心过程,它涉及了多个步骤以确保Bean能够正确地被创建并注入到应用上下文中。

Bean定义注册:

  • 首先,你需要在Spring的配置文件(如XML配置文件或Java配置类)中定义Bean。这包括指定Bean的类名、作用域、初始化方法、销毁方法以及可能的依赖关系等。

  • Spring容器会读取这些配置,并将Bean定义信息存储在其内部的数据结构中,通常是BeanDefinition对象。

实例化前的准备:

  • 在实例化Bean之前,Spring会进行一些准备工作,如解析Bean定义中的属性、检查依赖关系等。

  • 如果Bean定义中引用了其他Bean,Spring会尝试先解析并实例化这些依赖Bean。

实例化:

  • 实例化是创建Bean对象的过程。Spring提供了多种实例化Bean的方式:

    • 构造器实例化:通过调用Bean的构造方法来创建实例。你可以在配置文件中指定要使用的构造方法,并提供相应的参数。

    • 静态工厂方法实例化:通过调用静态工厂方法来创建Bean实例。你需要在配置文件中指定工厂类的类名和工厂方法的名称。

    • 实例工厂方法实例化:首先实例化一个工厂Bean,然后调用该工厂Bean的某个非静态方法来创建目标Bean实例。

    • 默认构造器实例化:如果Bean定义中没有指定其他实例化方式,并且Bean类有一个无参构造器,那么Spring将使用默认构造器来实例化Bean。

  • 实例化完成后,你得到的是一个原始的对象,它还没有进行任何属性注入或初始化。

属性注入:

  • 在Bean实例化之后,Spring会进行属性注入(也称为依赖注入)。这包括将Bean定义中指定的属性值或对其他Bean的引用注入到Bean的相应属性中。

  • Spring支持多种属性注入方式,如基于字段的注入、基于setter方法的注入和基于构造器的注入等。

BeanPostProcessor处理:

在Bean的属性注入完成后,但Bean的初始化方法执行之前,Spring会调用已注册的BeanPostProcessor接口的postProcessBeforeInitialization方法。这是一个可选的步骤,你可以通过实现该接口并注册相应的BeanPostProcessor来在Bean初始化前后执行自定义的逻辑。

初始化:

  • 接下来,Spring会调用Bean定义中指定的初始化方法(如果有的话)。这通常是在Bean类中定义的某个方法,并用特定的注解(如@PostConstruct)或XML配置中的元素的init-method属性来指定。

  • 初始化方法是Bean在准备好接受请求之前进行必要设置或执行特定任务的地方。

BeanPostProcessor再处理:

在Bean初始化方法执行之后,Spring会再次调用已注册的BeanPostProcessor接口的postProcessAfterInitialization方法。这是另一个可选的步骤,你可以在这里执行一些清理或后处理操作。

Bean就绪:

经过上述步骤后,Bean就已经被完全创建并初始化了。现在它可以被应用上下文中的其他组件使用或注入到其他Bean中。

到这里,我们的实例化就说完了,记下来看第二阶段。

Bean的设置属性阶段

Bean的设置属性阶段(也称为属性注入或依赖注入)是Bean生命周期中的一个重要环节。这个阶段发生在Spring容器创建Bean的实例之后,但在Bean被实际使用之前。

  • 当Spring容器创建一个Bean的实例后,它会检查该Bean是否有需要注入的属性。这些属性可能是其他的Bean、基本数据类型、集合、Map等。

  • Spring会查找与这些属性对应的配置信息(可能是XML中的标签、注解中的值或其他配置方式),并将它们注入到Bean的相应字段或setter方法中。

注入方式:

  • 字段注入:通过直接在字段上使用@Autowired或其他相关注解来实现。但请注意,字段注入在某些情况下可能导致测试困难或难以遵循良好的封装原则。

  • 构造函数注入:在构造函数参数上使用@Autowired或其他相关注解。这是推荐的方式之一,因为它确保了Bean在创建时就已经拥有所有必需的依赖项,并且这些依赖项是不可变的。

  • setter方法注入:在setter方法上使用@Autowired或其他相关注解。这种方式允许Bean在创建后的某个时间点接收其依赖项。

既然我们已经把这个属性设置完毕了,那么就要开始后进行初始化阶段了。

Bean 的初始化

  • Bean Aware接口回调

  • Bean初始化前操作

  • Bean初始化操作

  • Bean初始化后操作

  • Bean初始化完成操作

BeanAware接口回调

  private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}

Bean初始化前操作

  @Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessBeforeInitialization(result, beanName);if (result == null) {return result;}}return result;
}

Bean初始化操作

调用InitializingBean接口的afterPropertiesSet方法 调用定义bean的时候指定的初始化方法。

 public interface InitializingBean {/*** Invoked by the containing {@code BeanFactory} after it has set all bean properties* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.* <p>This method allows the bean instance to perform validation of its overall* configuration and final initialization when all bean properties have been set.* @throws Exception in the event of misconfiguration (such as failure to set an* essential property) or if initialization fails for any other reason*/void afterPropertiesSet() throws Exception;} 

Bean初始化后阶段

 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}

Bean初始化完成操作

public interface SmartInitializingSingleton {/*** Invoked right at the end of the singleton pre-instantiation phase,* with a guarantee that all regular singleton beans have been created* already. {@link ListableBeanFactory#getBeansOfType} calls within* this method won't trigger accidental side effects during bootstrap.* <p><b>NOTE:</b> This callback won't be triggered for singleton beans* lazily initialized on demand after {@link BeanFactory} bootstrap,* and not for any other bean scope either. Carefully use it for beans* with the intended bootstrap semantics only.*/void afterSingletonsInstantiated();}

当我们完成了初始化之后,使用完成,最后 Bean 就要走到销毁阶段了。

Bean 的销毁

 @Overridepublic void destroyBean(Object existingBean) {new DisposableBeanAdapter(existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();}

这里需要注意的是

  • 当容器关闭时,或者当单例 Bean 的作用域结束时,Spring 会销毁 Bean 的实例。

  • 对于非单例 Bean(如 prototype 作用域的 Bean),它们会在每次请求时创建,并在不再需要时由 Java 的垃圾回收机制销毁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于高光谱数据集的创新点实现-高斯核函数卷积神经网络

一、高光谱数据集简介 1.1 数据集简介 数据集链接在这:高光谱数据集(.mat.csv)-科研学术 数据集包含下面三个文件&#xff1a; 文件中包含.mat与.csv,145x145x220, 其实主要使用avirissub.csv文件&#xff0c;在代码上只是将mat文件转成了csv文件。具体avirissub.csv如下&am…

计算机网络-BGP基础概念

一、BGP的基本概念 BGP是一种实现自治系统AS之间的路由可达&#xff0c;并选择最佳路由的矢量性协议。早期发布的三个版本分别是BGP-1&#xff08;RFC1105&#xff09;、BGP-2&#xff08;RFC1163&#xff09;和BGP-3&#xff08;RFC1267&#xff09;&#xff0c;1994年开始使用…

企业微信群发群消息:策略、技巧与效果优化

在数字化营销日益盛行的今天&#xff0c;企业微信已成为企业与客户、员工之间沟通的重要桥梁。其中&#xff0c;群发群消息功能更是企业快速传递信息、提升沟通效率的关键工具。本文将深入探讨企业微信群发群消息的策略、技巧以及效果优化方法。 一、企业微信群发群消息的重要…

TiDB-从0到1-MVCC

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCC 一、MVCC Multi-Version Concurrency Control 多版本并发控制&#xff0c;其主要解决了读并发的问题。 其维持一个数据的多个版本使读写操作没有冲突。也就是说数据元素X…

oracle linux7安装oracle11g0204

1、平时需要修改 /etc/redhat-release文件为Red Hat Enterprise Linux 7,这次不需要了。 2、关闭selinx nano /etc/selinux/config 改为disabled 3、nano /etc/hosts 修改解析 在oracle服务器中增加 /etc/hosts中一个对应 192.168.1.10 CLOUD-MC-SQL1 4、修改系统文件 /…

虚拟机报错:VMX 进程已提前退出。VMware Workstation 无法连接到虚拟机。

解决报错&#xff1a;VMware Workstation 无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录。 VMX 进程已提前退出。 解决方案&#xff1a;右键桌面图标进入VMware Workstation Pro的属性设置&#xff0c;兼容性–勾选“以管理员…

【windows】Total Uninstall:一款功能强大的完全卸载软件

软件介绍 Total Uninstall是一款专业的软件卸载工具&#xff0c;旨在帮助用户彻底地清除计算机上的应用程序&#xff0c;包括与应用程序相关的所有文件和注册表项。以下是Total Uninstall的一些主要功能和特点&#xff1a; 完全卸载&#xff1a;软件可以监视应用程序的安装过程…

【C++题解】1321. 时钟旋转(2)

问题&#xff1a;1321. 时钟旋转&#xff08;2&#xff09; 类型&#xff1a;字符串 题目描述&#xff1a; 时钟从时间&#xff1a;xx:xx&#xff08;xx时xx分&#xff09;&#xff0c;走到时间&#xff1a;xx:xx&#xff08;xx时xx分&#xff09;&#xff0c;时针共旋转了多…

uniapp一些问题解决

1.按钮边框如何去除&#xff1f; 参考博主&#xff1a;微信小程序按钮去不掉边框_微信小程序button去掉边框-CSDN博客文章浏览阅读1k次。最近在学uni-app&#xff0c;顺便自己写个小程序。左上角放了个button&#xff0c;可边框怎么也去不掉…原来微信小程序的按钮要去掉边框要…

新零售数据中台:打造智能商业运营的核心引擎_光点科技

随着数字化转型的浪潮席卷全球&#xff0c;新零售行业正在经历一场前所未有的革新。在这一过程中&#xff0c;“新零售数据中台”逐渐成为企业构建智能商业运营的核心引擎。本文将重点介绍新零售数据中台的概念、其在新零售中的作用&#xff0c;以及如何通过数据中台实现商业价…

npm yarn 更换国内源以及node历史版本下载地址【超简洁步骤】

npm 更换国内源 npm config set registryhttps://registry.npmmirror.com npm config set electron_mirrorhttps://registry.npmmirror.com/electron/yarn 更换国内源 yarn config set registry https://registry.npmmirror.comnode历史版本下载地址 https://nodejs.org/dow…

基于YOLOV8/YOLOV5的远距离停车场车位检测识别系统

摘要&#xff1a; 在本文中深入探讨了基于YOLOv8/v7/v6/v5的停车位检测系统&#xff0c; 开发远距离停车位检测系统对于提高停车效率具有关键作用。。本系统核心采用YOLOv8技术&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;以便进行性能指标对比。深入解释了YOL…

【QT环境配置】节约msvc2017灰色不可用问题

1. 问题 msvc2017不可用&#xff0c;2019、2022都同理解决。 2. 解决 第一步&#xff1a;打开控制面板->程序->程序和功能->找到自己安装的vs程序->鼠标右键后出现卸载更改->点击更改。 找到下面组件即可。&#xff08;msvc2019就找msvcv142&#xff09; …

SQL刷题笔记day5

SQL218题目 我的错误代码&#xff1a; select de.dept_no,de.emp_no,s.salary from employees e join dept_emp de on de.emp_no e.emp_no join salaries s on s.emp_no e.emp_no where de.dept_no not in dept_manager.dept_no #not in 好像不能直接这样用 这里报错 正确代…

宝兰德入选“鑫智奖·2024金融数据智能运维创新优秀解决方案”榜单

近日&#xff0c;由金科创新社主办、全球金融专业人士协会支持的“2024 鑫智奖第六届金融数据智能优秀解决方案”评选结果正式公布。凭借卓越的技术实力和方案能力&#xff0c;宝兰德「智能全链路性能监控解决方案」从90个参选方案中脱颖而出&#xff0c;荣誉入选“鑫智奖2024金…

Ajax与Axios

Ajax和Axios都是用于在前端进行数据交互的工具&#xff0c;但它们有一些重要的区别&#xff0c;从使用方式到功能特性都有所不同。 Ajax&#xff1a; Ajax(Asynchronous JavaScript and XML)是一种用于创建异步请求的技术。它使用原生的XMLHttpRequest对象或者更现代的Fetch A…

【ArcGISPro】3.1.5下载和安装教程

下载教程 arcgis下载地址&#xff1a;Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本&#xff0c;它引入了一些新的特性和功能&#xff0c;以提高用户的工作效率和数据分析能力。以下是ArcGIS…

后台接口返回void有设置response相关内容,前端通过open打开接口下载excel文件

1、引入依赖&#xff0c;用来生成excel <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.2</version></dependency> 2、接口类代码如下&#xff1a; /*** 企业列表--导出*/Api…

2024年150道高频Java面试题(七十五)

149. MyBatis 中的动态 SQL 是什么&#xff0c;如何使用&#xff1f; MyBatis 中的动态 SQL 是指可以在 XML 映射文件中编写可适应不同情况的 SQL 语句&#xff0c;它允许 SQL 语句根据传入的参数或查询条件动态构建。这样的特性让开发者可以编写更加灵活和强大的查询&#xf…

Vue进阶之Vue项目实战(四)

Vue项目实战 出码功能知识介绍渲染器性能调优使用 vue devtools 进行分析使用“渲染”进行分析判断打包构建的产物是否符合预期安装插件使用位置使用过程使用lighthouse分析页面加载情况使用performance分析页面加载情况应用自动化部署与发布CI/CD常见的CI/CD服务出码功能 出码…