【俯瞰Spring】二、Bean的生命周期

一、前言

同人有生老病死一样,在Spring中IoC容器管理的Bean也具备实例化、初始化、销毁一整套完整的生命周期。有了生命周期,Ioc容器就能在生命周期的各个阶段对Bean的功能进行扩展或增强,比如我们自定义的init方法、destroy方法、以及Aop代理等,都是围绕Bean的生命周期在特定阶段来完成定制化的功能,所以说掌握Spring Bean生命周期是进阶为Spring高阶玩家必须迈出的第一步!


二、Bean的生命周期

通常说Spring Bean的生命周期,指的是Bean的初始化这一步,不过楼主觉得,没有鸡哪来蛋,如【俯瞰Spring】一、Spring核心工作机制,Bean的源头都是从Bean定义开始,故宽泛点来理解,Bean生命周期从Spring容器启动开始,生成Bean定义、实例化、完成依赖注入、初始化,再到最终Spring容器销毁Bean。放张图,直观感受下:
在这里插入图片描述


三、Bean生命周期剖析

有了上图的整体印象,我们在针对每个阶段,深入局部窥视下,有图真香!
在这里插入图片描述

3.1 Bean定义生成、注册

如第一幅图所示,从Bean定义产生到最终注册Bean定义,中间Spring留了一个扩展点BeanFactoryPostProcessor.postProcessBeanDefinitionRegistry()
用于修改Bean定义;易见,这个扩展点的触发时机是Bean定义加载已完成,但还没开始实例化、初始化之前。

其最最重要的一个实现类是 ConfigurationClassPostProcessor, 几个重要注解如@Configuration@Import@Bean 都是由这个类承担的。后续会开文单独介绍,这里不再展开。

3.2 实例化

3.2.1实例化是什么?

所谓实例化,说白了就是new对象呗。如上图所示,Spring有三种方式来new对象:

  • 通过FactoryMethod实例化,多用在@Bean;
  • 推断出合适的构造方法, 通过构造方法实例化(怎么推断这块有点复杂,先不展开)
  • 采用喜闻乐见的无参构造方法

3.2.2 扩展点

在实例化这个阶段的前、后,Spring提供了两处扩展: InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

InstantiationAwareBeanPostProcessor 比较重要的实现类为AnnotationAwareAspectJAutoProxyCreator。光从名字就能看出这个类跟生成Aop代理有关,那是不是在这个阶段生成了Aop代理呢?No!记住一点,既然是代理,那必须有被代理的目标对象,皮之不存,毛将焉附!因为这时候目标对象都还不完整,甚至都没被new出来。

存在即合理,Spring的大师搞这个东东肯定有目的。实际上AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation()做了识别解析Aspect切面,Aop中常用的几个注解:@Around@Before@After@AfterReturning@AfterThrowing 就是在这里增强的

3.3 依赖注入

依赖注入这一阶段,就是将对象依赖的属性挨个填充。比如:ControllerA依赖了ServiceB、ServiceC,那么依赖注入干的活就是把ControllerA的两个属性ServiceB、ServiceC都填充好。

Spring的依赖注入主要是InstantiationAwareBeanPostProcessor.postProcessPropertyValues() 这个BeanPostProcessor来完成,细节不展开!

3.4 初始化

初始化,这个阶段细节非常多,也都很重要。如上图那个大框框里面。

  • invokeAwareMethods() 方法
    如果发现实例对象是XXXAware实例,则直接强转调用setXXX()方法

  • applyBeanPostProcessorsBeforeInitialization()方法
    用到 Spring容器最新核心的扩展接口BeanPostProcessor.postProcessBeforeInitialization(); 图中楼主特意把ApplicationContextAwareProcessor
    CommonAnnotationBeanPostProcessor 列举出来:
    ApplicationContextAwareProcessor 同XXXAware一样,做了两件比较重要的事:EnvironmentAware.setEnvironment()ApplicationContextAware.setApplicationContext()
    CommonAnnotationBeanPostProcessor 则处理了 @PostConstruct 注解,即我们加上该注解的方法,就是在这里被触发调用的

  • invokeInitMethods() 方法
    如果我们的实例是InitializingBean的实现类,则会被强转触发afterPropertiesSet()方法
    如果我们的实例,有自定义的init方法: 如@Bean自定义的init方法,那么就Spring就会帮我们触发下自定义的init方法

  • applyBeanPostProcessorsAfterInitialization() 方法
    楼主单独列了下 AbstractAutoProxyCreator,这家伙的 postProcessAfterInitialization()方法就是用来创建AOP代理的!

3.5 销毁

初始化完成之后,这时候的Bean就是一个有血有肉的Bean,该依赖的都注入了,该触发的init方法也触发了,甚至这个bean还可能已被aop代理狸猫换太子了;不过,有些bean还需要感知到容器关闭,以便在容器关闭时,做一些资源释放(比如: 关闭连接、关闭线程池);这种Bean就需要接受Spring的特殊关注,单独登记起来;实现途径有三种: @PreDestroy 注解的方法、实现 DisposableBean 接口、@Bean指定destroy方法


四、总结

本文通过2幅图,先整体后局部讲解了Spring Bean的生命周期,相关知识点概括如下:

  • Bean的生命周期:包含Bean定义的生成及注册、实例化、依赖注入、初始化、销毁几个阶段
  • 修改Bean定义的扩展点: BeanFactoryPostProcessor
  • 依赖注入: InstantiationAwareBeanPostProcessor
  • 实例化前、后的扩展点: InstantiationAwareBeanPostProcessor(这个类不仅干了依赖注入还参与了实例化)
  • 初始化前、后的扩展点: BeanPostProcessor,特别是其实现类 CommonAnnotationBeanPostProcessor 和 AbstractAutoProxyCreator
  • Bean的init方法三种实现方式:1、@PostConstruct 注解的方法;2、实现 InitializingBean接口;3、通过xml或@Bean值定init方法
  • Bean的destroy方法三种实现方式:1、@PreDestroy 注解的方法;2、实现 DisposableBean 接口;3、通过xml或@Bean指定destroy方法
发布了27 篇原创文章 · 获赞 4 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/caiguoxiong0101/article/details/104622853