前言
关于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生命周期的内容,并不只是为了面试,其中扩展接口的设计思想、扩展接口在功能特性都可以应用到业务开发中。