Spring Bean的生命周期加载过程

378 阅读3分钟

Spring 作为我们日常开发使用最多的一个框架,它主要是基于它的IOC(控制反转)和AOP(切面)和DI(依赖注入)来实现的,我们项目中的Java Bean都会交给Spring的IOC容器来管理,其中Bean的加载过程也是相对复杂了,也是我们看了之后容易忘记的,包括我在之前面试了过程中也多次被问到,我以我的角度来分析下Bean的生命周期和加载过程到底是怎样的,如有地方分析不对的请大家指出🙏

Bean的生命周期

Spring中的bean的生命周期大的方面主要分为四个阶段:实例化Bean—>Bean的属性填充—>初始化bean—>销毁bean

实例化Bean

首先我们看这个BeanFactoryPostProcessor这个接口,这就是bean在实例化开始调用的接口,里面有一个方法postProcessBeanFactory(),这个接口有很多的实现类。

B166EDEA-35CE-4512-88E1-5BAF89E2BD53.png 我们着重看AbstractDependsOnBeanFactoryPostProcessor这个抽象类型的实现,重写了postProcessBeanFactory()方法。

DAE17891-E901-4F54-B875-782AC0F7635D.png

07E3861C-0BBA-4C55-9651-29384160FB0E.png 看到会去通过循环beanName来通过BeanDefinition这个类来查创建对象,BeanDefinition是Spring中非常核心的概念,BeanDefinition可以看到实际是创建了一个ConcurrentHashMap来存放beanName。

6683BEA6-6362-462D-931C-1996377935AC.png

F769ADBF-89ED-4368-B6C7-AFA2EE2B970B.png BeanPostProcessor接口会有两个方法一个是Before,另一个是After方法,一个是在实例化之前调用,一个是在实例化之后调用。InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,一般继承适配器类InstantiationAwareBeanPostProcessorAdapter去使用它,执行bean的构造器的postProcessPropertyValues()方法,这块用到的设计模型是适配器模式。

Bean的属性填充

794480A6-06A2-4F29-A20A-380956AD5001.png

5385A449-A811-46B9-B141-41817C905246.png

Aware接口,Spring用来进行属性填充的父接口,BeanNameAware继承父接口调用setBeanName方法来完成属性注入,如果实现了BeanFactoryAware 则调用setBeanFactory方法,这里完成属性的填充后需要调用BeanPostProcessor接口的postProcessBeforeInitialization,这个方法的调用会在Bean构造完成之后,初始化init-method方法执行之前被调用。

这里看下postProcessBeforeInitialization 方法的两个入参

  • Object bean: 刚刚由Spring实例化出来的Bean
  • String beanName,在Spring配置元数据中Bean的名称(id or name) 这里返回的Bean不是入参里面的Bean,会重新返回一个Bean,之前在Spring容器配置的Bean会被覆盖。

初始化bean

EC91732A-441C-47AD-8CCA-1C4C23860E96.png Bean在初始化的时候,如果实现了InitializingBean接口则会调用afterPropertiesSet方法来进行初始化,如果通过配置文件配置了init-method属性指定了初始化方法,那么也会在实例化完成之后调该属性指定的初始化方法进行初始化。 下面该调用postProcessAfterInitialization方法,对初始化完成的Bean进行后置处理,它与postProcessBeforeInitialization方法基本一致,只不过是在init-method被容器调用之后执行的。 到这里面,我们的Bean就可以使用了,程序执行业务逻辑,它会一直在应用的上下文中,直到调用destory()方法进行销毁。

销毁bean

A510D009-107E-4AF6-BA82-8C69822724A3.png 如果Bean实现了DisposableBean接口,并且调用了destroy()方法会对上下文中的Bean进行销毁。 如果配置文件中指定了destroy-method属性,则去调属性指定的方法进行销毁。