Springboot扩展点系列之终结篇:Bean的生命周期

news/2024/10/30 13:34:31/

前言

关于Springboot扩展点系列已经输出了13篇文章,分别梳理出了各个扩展点的功能特性、实现方式和工作原理,为什么要花这么多时间来梳理这些内容?根本原因就是这篇文章:Spring bean的生命周期。你了解Spring bean生命周期,这个问题,想回答好其实并不容易,问题太大,涉及到点很多,也复杂,当然在实际业务开发中,这些内容Spring已经帮我们完成了,所以Spring、Springboot用起来才会如此简洁、高效。而这正是我想这件事弄清楚,并分享给更多人的原因:学习优秀的思想,把复杂的事情简单化。

而这篇文章的重点,就是把所有的扩展点串连在一条线上,从宏观和微观分别去了解一下Springboot中bean的生命周期。

Bean的生命周期

Bean的生命周期指的是什么?

简单理解,Spring bean的生命周期,就是普通java类变为Spring管理的Bean的过程,即Spring的核心之一控制反转,即把原来对象创建的控制权由用户程序交由Spring管理。而Spring对普通java类的管理,大致分为两步:第一,先把纳入到Spring管理的java类抽象为一个beanDefinition对象;第二,再根据beanDefinition完成java类的实例化、属性注入、其他的一些Spring特有的扩展操作;第三,这时就可以使用Spring管理的bean,直到bean被销毁。通过这三步普通java类完成了到Spring bean的一个转变,或者说宏观过程来看,这就是Spring bean一个生命周期过程。

普通java类到BeanDefinition

从普通的java类到BeanDefinition,通常有两种方式:

1、在xml中使用等标签进行标记注册;

2、直接在java类上,使用注解形式,如@Component、@Controller、@Service、@Configuration等;

3、第三种比较特殊,利用Spring提供的一些扩展点,直接硬编码的形式实例化好的bean进行注册,如实现FactoryBean接口;

从BeanDefinition到bean的销毁

平时看到的大部分文章的分享,基本是都是分享的这一阶段的内容,这一部分也是步骤最多、逻辑较为复杂的一部分,但是只要把据好两个关键时机,这一部分也可以变得很简单,那这两个时机是什么呢?就是bean的实例化、bean的属性注入。有的小伙伴看源码,看着看着都云里雾里,思路不知道都偏到哪里去了,最后脑子里一片茫然,这是因为没有把握好Bean生命周期的关键。

Bean生命周期的关键是什么呢?答案就是Bean,这可不是废话。不信你试试,所有分析都不要离开bean,牢牢盯好bean在生命周期过程中的变化,你看还会在源码里迷路不?

bean的实例化,也不神秘,即通过java反射调用无参数构造方法或有参数构造方法进行bean实例化,默认是调用无参数构造方法;bean属性注入是指引用Spring容器内对象的属性赋值,即依赖注入;我觉得Spring之所以伟大,除了以上部分,Spring bean生命周期最为值得研究和学习的就在于Bean实例过前后各种丰富、灵活的扩展操作,不仅Spring自己内部在使用,也以接口的形式对外由开发者按自己需要进行实现。因此,我花了一些时间,输出一系列的文章来分享Spring扩展点的功能特性、实现方式、工作原理,如果想从更加微观的角度去了解Spring bean生命周期,可以参考阅读下面这些文章:

1、Springboot扩展点之ApplicationContextInitializer

2、Springboot扩展点之BeanFactoryPostProcessor

3、Springboot扩展点之BeanDefinitionRegistryPostProcessor

4、Springboot扩展点之BeanPostProcessor

5、Springboot扩展点之InstantiationAwareBeanPostProcessor

6、Springboot扩展点之SmartInstantiationAwareBeanPostProcessor

7、Springboot扩展点之ApplicationContextAwareProcessor

8、Springboot扩展点之@PostConstruct

9、Springboot扩展点之InitializingBean

10、Springboot扩展点之SmartInitializingSingleton

11、Springboot扩展点之CommandLineRunner和ApplicationRunner

12、Springboot扩展点之FactoryBean

13、Springboot扩展点之DisposableBean

Spring bean生命周期流程图如下:

Spring bean生命周期涉及主要接口、类的UML关系图如下:

Spring bean生命周期过程,很复杂,但是也有条不紊,主要涉及的的扩展接口有ApplicationContextInitializer、BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor、InstantiationAwareBeanPostProcessor、InitializingBean、BeanPostProcessor、SmartInitializingSingleton、CommandLineRunner、DisposableBean。接口看起来不少,实际上可以分为三类:

1、beanFactory级别:仅在Spring容器启动时执行一次,ApplicationContextInitializer、BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor;

2、bean级别:每个bean实例化、依赖属性注入前后都会触发,InstantiationAwareBeanPostProcessor、BeanPostProcessor;

3、bean自身的方法:bean需要通过属性指定、注解标记或实现接口,如init-method、destroy-method、@PostConstruct注解标记的方法、InitializingBean、DisposableBean、FactoryBean、SmartInitializingSingleton、CommandLineRunner;

概括一下Spring bean生命周期:

1、在Spring容器开始启动到Spring bean(这里主要是指业务中的非懒加载的单例bean)实例化前,是beanFactory级别的扩展接口触发执行,整个生命周期仅执行一次,如ApplicationContextInitializer、BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor;

2、接着通过反射调用bean的构造方法完成bean实例化、bean依赖属性注入;

3、在bean实例化、bean依赖属性注入的前后,bean级别的扩展接口、bean自向的方法触发执行,直到bean销毁,Spring bean的生命周期结束;

面试中经常问Spring Bean生命周期的目的是什么?

其实这个问题对于面试者业说不好回答,因为它实际涉及的内容很多、很广,但是面试官爱问也是有原因的,面试官通过这个问题可以考察到面试者对于Spring从宏观到微观的认识有多深,如果面试者的回答只是几分钟、三言两语,面试官基本上可判定面试者的技术水平比较初级了;如果面试者就这一个问题能聊上一个半小时,依然没有要结束的意思,那么说明面试者对这块理解比较深刻,能力水平自然不必说了。

在面试中,怎么才能回答好这个问题呢?

如果面试官不问你Spring bean的生命周期,是不是学习Spring bean生命周期就没有用了呢?

当然不,Spring生命周期的内容,是Spring的核心、灵魂。不管面试官问什么,你都可以往这上面引。

比如说,面试官问:”平时开发过程中使用Spring boot吗?对Springboot你的理解是什么?“

相信大多数的java项目都会使用Spring、Springboot,可以这样回答:Springboot实际上按约定大于配置的开发原则,对Spring原来XML配置的方式进行简化、包装,可以达到开箱即用,简化开发,提高开发效率,但是其核心依然是Spring。(话锋一转,开始往Spring生命周期上引),而Spring的最重要的核心是IOC,IOC管理的对象就是Spring bean,Spring bean生命周期内的又提供了各种优秀扩展接口和内部实现,也可以根据业务需要自定义实现,非常灵活和方案。然后就可以慢慢聊有哪些扩展接口、功能特性是什么、怎么使用、工作原理是什么,聊上三四个扩展接口,半个小时都不够用。

总结

当然,学习Spring生命周期的内容,并不只是为了面试,其中扩展接口的设计思想、扩展接口在功能特性都可以应用到业务开发中。


http://www.ppmy.cn/news/26903.html

相关文章

CMake构建静态库与动态库以及使用

CMake构建静态库与动态库一、任务二、准备工作三、编译共享库四、ADD_LIBRARY指令五、编译静态库5.1、SET_TARGET_PROPERTIES指令5.2、GET_TARGET_PROPERTY指令六、动态库版本号七、安装共享库和头文件八、使用外部共享库和头文件8.1、准备工作8.2、引入头文件搜索路径8.3、为 …

openCV—图像入门(python)

目录 目标 使用OpenCV 显示图像 写入图像 总结使用 使用Matplotlib 注:图片后续补充 目标 在这里,你将了解如何使用Python编程语言中的OpenCV库,实现读取、显示和保存图像的功能。具体来说,你将学习以下函数的用法:cv.imread() 用于读取图像,cv.imshow() 用于显示…

【1】linux命令每日分享——mkdir创建目录

大家好,这里是sdust-vrlab,Linux是一种免费使用和自由传播的类UNIX操作系统,Linux的基本思想有两点:一切都是文件;每个文件都有确定的用途;linux涉及到IT行业的方方面面,在我们日常的学习中&…

工信部印发《关于电信设备进网许可制度若干改革举措的通告》(附解读)

导 读 工业和信息化部近日印发《关于电信设备进网许可制度若干改革举措的通告》,内容包括调整部分电信设备监管方式、精简优化进网许可检测项目、公布进网许可审批承诺时限、延长进网试用批文有效期、实行电信设备产品系族管理等五项改革举措,自今年3月…

Python每日一练(20230221)

目录 1. 不同路径 II 2. 字符串转换整数 (atoi) 3. 字符串相乘 1. 不同路径 II 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中…

6——JVM调优工具详解及调优实战

Jmap、Jstack、Jinfo命令详解 Jmap 此命令可以用来查看内存信息,实例个数,以及占用内存大小 生成dump文件 把dump文件装入Jvisvalvm进行分析 Jstack Jstack加进程id查找死锁 Jstack找出占CPU最高的线程堆栈信息 top -p 进程号:显示进程…

DAX 微信 markdown 编辑器

DAX 微信 markdown 编辑器 一、致谢 感谢开源项目: md wechat-format 感谢 WordPress 插件 Mine云点播 作者 mine27 的指导。 二、如何使用 打开如下地址,直接编辑,可以实时看到符合微信公众号排版的效果。 推荐访问:https://j…

2023.2 新方案 java代码混淆 java加密 字符串加密

Java字节码可以反编译,特别是创业公司,很好的项目很容易被别人破解反编译,造成很严重的损失,所以本混淆方案能很好的保护源码,而且在不断迭代,增强混淆效果,异常问题处理,达到保护项目的目的: 本次升级包括: 2023年02年19日 : ht-confusion-project-1.8…