【Spring】关于Spring中Bean的生命周期

1、生命周期概括图

首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy。Spring中Bean的生命周期也类似,可以用下图概括:
在这里插入图片描述
现在我们就根据上面的步骤来分析一下每一步的实际实现是怎样的。(以下基于spring-boot Version 2.7.6分析)

2、源码分析

我们创建一个示例代码,从而方便进入查看源码。自定义一个BeanBeanPostProcessor

class MyBean implements ApplicationContextAware, BeanNameAware {

    private MyBeanPostProcessor myBeanPostProcessor;

    public MyBean(){
        System.out.println("创建了一个myBean,构造器注入");
    }

    @Autowired
    public void setMyPostProcessor(MyBeanPostProcessor myBeanPostProcessor){
        System.out.println("Setter注入");
        this.myBeanPostProcessor = myBeanPostProcessor;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("执行ApplicationContextAware接口,实际用ApplicationContextBeanPostProcessor执行");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("执行BeanNameAware,name为:" + name);
    }

    @PostConstruct
    public void init(){
        System.out.println("初始化Bean");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("销毁Bean");
    }
}
class MyBeanPostProcessor implements  BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化前" + beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化后" + beanName);
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

再创建一个测试类:

class MySpringboot001ApplicationTests {

    @Test
    void contextLoads() {
    	// Spring容器创建
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 注册配置类(创建BeanDefinition)
        applicationContext.register(MyBeanPostProcessor.class);
        applicationContext.register(MyBean.class);
        // 加载刷新配置(这一步才会创建Bean)
        applicationContext.refresh();
    }

}

2.1 Spring容器创建

如代码所示,我们手动创建了一个Spring容器AnnotationConfigApplicationContextAnnotationConfigApplicationContext 是 Spring 框架提供的一个用于基于注解的配置方式创建和管理 Spring Bean的高级容器。以下是创建容器的源码:
在这里插入图片描述

2.2 扫描或者注册配置类

我们往容器中注册两个Bean,进入register方法:
在这里插入图片描述

2.3 生成BeanDefinition

接着一直到org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
在这里插入图片描述
进入org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
在这里插入图片描述
进入org.springframework.context.support.GenericApplicationContext#registerBeanDefinition
在这里插入图片描述

2.4 把BeanDefinition放进beanDefinitionMap<beanName, BeanDefinition>中

最后进入org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
在这里插入图片描述
BeanDefinition 是 Spring 框架中的一个概念,用于描述和定义一个 bean 的元数据信息。每个被 Spring 管理的 bean 都对应着一个 BeanDefinition 对象。
BeanDefinition 中主要包含了以下关键信息:

  • Class:表示该 bean 的类。

  • Scope:表示该 bean 的作用域(例如单例、原型等)。

  • 构造函数参数和属性值:表示构造函数参数和属性的值。

  • 依赖关系:表示该 bean 依赖的其他 bean 的名称或类型。

  • 生命周期回调方法:表示该 bean 的初始化方法和销毁方法。

  • 懒加载:表示该 bean 是否延迟加载。

到这里结束,Spring已经注册和扫描完成了,private final Map<String, BeanDefinition> beanDefinitionMap中保存了该容器中的所有bean的BeanDefinition

2.5 单例Bean生成

我们进入org.springframework.context.support.AbstractApplicationContext#refresh方法,该方法是创建Bean工厂和创建单例Bean的入口方法:
在这里插入图片描述
进入org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
在这里插入图片描述

2.6 遍历beanDefinitionNames、筛选出非懒加载且是单例的Bean、合并BeanDefinition

进入org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
在这里插入图片描述
进入org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
在这里插入图片描述
进入org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
在这里插入图片描述
进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
在这里插入图片描述

我们先进入工厂方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
在这里插入图片描述
进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean,该方法才是创建Bean的最主要的方法。创建出来的Bean是封装在BeanWrapper中的,这是方便后面的填充Bean(依赖注入)和初始化Bean等操作:
在这里插入图片描述

2.7 推断构造方法

进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
在这里插入图片描述
该方法主要是推断构造方法,选择一个合适的构造方法去实例化Bean。推断规则请看【Spring】关于Spring的三种注入方式的分析的构造注入说明。

进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
在这里插入图片描述
进入org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
在这里插入图片描述

2.8 实例化(创建Bean)

进入org.springframework.beans.BeanUtils#instantiateClass(java.lang.reflect.Constructor<T>, java.lang.Object...)
在这里插入图片描述
到这里,bean对象已经实例化完成了,注意构造器注入也是发生在这一步操作。

2.9 填充Bean(依赖注入)

回到前面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法中,我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
在这里插入图片描述
其中getBeanPostProcessorCache().instantiationAware是容器自定义的BeanPostProcessor,我们看一下里面有什么:
在这里插入图片描述

  • CommonAnnotationBeanPostProcessor处理@Resource 注解的属性注入和Setter注入;
  • AutowiredAnnotationBeanPostProcessor处理@Autowired@Value 注解的属性注入和Setter注入;
    这两个都实现了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties,它们实现的代码是差不多的,我们看一下AutowiredAnnotationBeanPostProcessor是如何实现这个方法的,进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
    在这里插入图片描述
    进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
    在这里插入图片描述
    进入org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
    在这里插入图片描述

从这里看到,Spring针对属性注入和Setter注入时,是先查找属性,再查找方法,并把它们放入List集合中,所以就有属性注入先于Setter注入执行。
我们看一下查找的逻辑方法org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation是怎样的:
在这里插入图片描述
autowiredAnnotationTypes封装了AutowiredAnnotationBeanPostProcessor能够处理的自动注入注解,我们看一下:
在这里插入图片描述

再回到前面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法中,我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
在这里插入图片描述
这个方法也是很重要的,主要是执行Ware接口的方法、初始化Bean以及初始化Bean前后的处理操作。

2.10 执行BeanXXXAware方法

我们进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
在这里插入图片描述
可以看到这里只执行BeanXXXAware接口的方法,至于ApplicationContextAware等接口,它们是由BeanPostProcessor实现的。

2.11 执行BeanPostProcessor处理器的初始化前方法

返回再进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
在这里插入图片描述
这里是主要就是执行每一个BeanPostProcessor处理器的初始化前方法。前面说ApplicationContextAware等接口,它们是由BeanPostProcessor实现的,我们先看getBeanPostProcessors()中有哪些BeanPostProcessor的bean:
在这里插入图片描述
可以看到有我们自定义的MyBeanPostProcessor,其他的是容器自动给我们生成的。我们看一下ApplicationContextAwareProcessor
在这里插入图片描述
可以看到确实是实现使用BeanPostProcessor处理器的方式实现的。

2.12 初始化Bean

返回再进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
在这里插入图片描述
这里就是执行我们给Bean自定义的初始化方法。

2.13 执行BeanPostProcessor处理器的初始化后方法

在返回进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
在这里插入图片描述
这个方法就是执行BeanPostProcessor处理器的初始化后方法。

到这里,这个Bean就算已经完成了初始化操作了,最后返回到org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)中:
在这里插入图片描述
进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton:
在这里插入图片描述
新创建的单例Bean放入singletonObjects中,这时候我们就可以使用这个bean了。

2.14 执行销毁方法

在容器关闭时或者容器被销毁时,就会执行Bean的销毁方法。我们进入org.springframework.context.support.AbstractApplicationContext#destroyBeans在这里插入图片描述
可以看到只会执行所有单例bean的销毁方法。

综上就是个人理解的Spring中Bean的生命周期,也许有些地方不够细节,后面有时间再补充。

  • 28
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值