欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring之Bean生命周期精简版

程序员文章站 2022-04-12 22:44:34
首先我们先看下Spring中Bean的生命周期的流程图,以下的源码分析也都是基于此流程图展开。AbstractApplicationContext的refresh是整个流程的核心,把这个方法的代码提出来逐个分析:@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 只是一些准备工作...

阶段1:Bean元信息配置阶段

这个阶段主要是bean信息的定义阶段。

Bean信息定义4种方式

  • API的方式

  • Xml文件方式

  • properties文件的方式

  • 注解的方式

阶段2:Bean元信息解析阶段

XML方式解析:XmlBeanDefinitionReader

properties文件定义bean的解析:PropertiesBeanDefinitionReader

注解方式:AnnotatedBeanDefinitionReader

阶段3:Spring Bean注册阶段

BeanDefinitionRegistry唯一实现:DefaultListableBeanFactory

大家可能看到有很多类也实现了BeanDefinitionRegistry接口,比如我们经常用到的AnnotationConfigApplicationContext,但实际上其内部是转发给了DefaultListableBeanFactory进行处理的,所以真正实现这个接口的类是DefaultListableBeanFactory

阶段4:BeanDefinition合并阶段

可能我们定义bean的时候有父子bean关系,此时子BeanDefinition中的信息是不完整的,比如设置属性的时候配置在父BeanDefinition中,此时子BeanDefinition中是没有这些信息的,需要将子bean的BeanDefinition和父bean的BeanDefinition进行合并,得到最终的一个RootBeanDefinition,合并之后得到的RootBeanDefinition包含bean定义的所有信息,包含了从父bean中继继承过来的所有信息,后续bean的所有创建工作就是依靠合并之后BeanDefinition来进行的。

阶段5:Bean Class加载阶段

这个阶段就是将bean的class名称转换为Class类型的对象

阶段6:推断构造方法

 

阶段7:Bean实例化前阶段

BeanPostProcessor是一个接口,还有很多子接口,这些接口中提供了很多方法,spring在bean生命周期的不同阶段,会调用上面这个列表中的BeanPostProcessor中的一些方法,来对生命周期进行扩展,bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的,所以如果大家想对bean的生命周期进行干预,这块一定要掌握好。

注意:本文中很多以BeanPostProcessor结尾的,都实现了BeanPostProcessor接口,有些是直接实现的,有些是实现了它的子接口。

Bean实例化之前会调用一段代码:

@Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

这段代码在bean实例化之前给开发者留了个口子,开发者自己可以在这个地方直接去创建一个对象作为bean实例,而跳过spring内部实例化bean的过程。

上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring自带的实例化bean的过程就被跳过了。

阶段8:Bean实例化

通过反射来调用bean的构造器来创建bean的实例

阶段9:对合并的BeanDefinition对象进行处理

会调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法

阶段10:Bean实例化后阶段

会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法

阶段11:Bean属性赋值阶段

循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中

阶段12:执行Aware接口

如果我们的bean实例实现了上面的接口,会按照下面的顺序依次进行调用:

BeanNameAware:将bean的名称注入进去
BeanClassLoaderAware:将BeanClassLoader注入进去
BeanFactoryAware:将BeanFactory注入进去

 阶段13:BeanProcessor的Before方法

会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回null,当前方法将结束通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。

这个接口有2个实现类,比较重要:

org.springframework.context.support.ApplicationContextAwareProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

ApplicationContextAwareProcessor注入6个Aware接口对象

如果bean实现了下面的接口,在ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中。

EnvironmentAware:注入Environment对象
EmbeddedValueResolverAware:注入EmbeddedValueResolver对象
ResourceLoaderAware:注入ResourceLoader对象
ApplicationEventPublisherAware:注入ApplicationEventPublisher对象
MessageSourceAware:注入MessageSource对象
ApplicationContextAware:注入ApplicationContext对象

从名称上可以看出这个类以ApplicationContext开头的,说明这个类只能在ApplicationContext环境中使用。

CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法

CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法

阶段14:Bean初始化方法

调用bean定义的时候指定的初始化方法,顺序是:注解-接口-xml

阶段15:BeanProcessor的After方法

调用BeanPostProcessor接口的postProcessAfterInitialization方法,返回null的时候,会中断上面的操作,通常称postProcessAfterInitialization这个方法为:bean初始化后置操作。

阶段16:Bean初始化完毕

阶段17:Bean使用阶段

这个阶段就不说了,调用getBean方法得到了bean之后,大家可以随意使用,任意发挥。

阶段18:Bean销毁阶段

触发bean销毁的几种方式

  1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean

  2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons

  3. 调用ApplicationContext中的close方法

Bean销毁阶段会依次执行

  1. 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法

  2. 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法

  3. 调用bean自定义的销毁方法

本文地址:https://blog.csdn.net/qq_24313635/article/details/109558947

相关标签: # Spring