「spring源码」spring中bean的创建流程,三级缓存、循环依赖问题

本文详细介绍了Spring中bean的创建流程,包括从三级缓存(singletonObjects, earlySingletonObjects, singletonFactories)获取bean,处理bean的创建、代理和组装,以及如何解决循环依赖问题。在bean创建过程中,Spring使用了bean后置处理器(InstantiationAwareBeanPostProcessor)进行对象包装,并通过JDK或Cglib实现动态代理。文章最后提到了Spring的循环依赖解决方案,通过三级缓存机制避免了死循环。" 88812033,7360454,C/C++字符串切分方法详解,"['C++', '字符串处理', 'C语言', 'Boost库']
摘要由CSDN通过智能技术生成

概述

在这里插入图片描述

上面的图大概画了整个bean的创建流程,spring在创建bean之前首先从缓存池中去getBean,当从缓存池中获取不到bean时,才会去创建bean。了解spring源码的同学知道,spring中有三级缓存:

  • 一级缓存:singletonObjects —> 存放完整bean的单例池
  • 二级缓存:earlySingletonObjects —> 存放非完整bean的单例池,存放早期暴露的bean
  • 三级缓存:singletonFactories —> 存放可以创建bean的factory,这里的factory主要是去创建bean的

代理对象
在创建bean的过程中,会通过bean后置处理去拿到bean的构造方法,对bean进行创建,然后对bean进行包装代理,如果bean不需要进行包装代理,就会返回一个早期暴露的对象,并放入二级缓存中,如果需要进行包装代理,就会返回一个factory,并放入三级缓存中。

然后会组装bean,这个过程就是去装配bean的属性,当bean装配完成后,bean就算是一个完整的bean了,最后会把这个完整的bean放入单例池中,即一级缓存中。

这就是bean创建的整个过程,这里概述了一下,也是想读到这篇文章的同学心里有一个大概,后面不至于晕乎乎的,下面就进入源码阅读阶段吧。

2.从缓存池中getBean

我们直接看doGetBean()这个方法,方法路径:AbstractBeanFactory#doGetBean(),在该方法最开始的时候就是去从单例池获取bean:
在这里插入图片描述

接下来就点进这个方法看看是怎么从缓存中获取bean的:
在这里插入图片描述

可以看到代码中,首先是从一级缓存中去拿bean,当拿不到bean时,且当前bean正在被创建,就会从二级缓存中去获取,当二级拿不到时,从三级缓存中获取factory对象,如果拿到了factory对象,会从factory中去获取bean,最后将该bean放入二级缓存中。

由于spring工程在启动时,缓存里肯定没有bean对象,于是就需要去创建bean,接下来看bean是如何创建的。

3.bean的创建

还是doGetBean()方法,看一下最重要的代码片段:
在这里插入图片描述

这里有两个方法,先看方法1,即createBean(beanName, mbd, args);点进这个方法去看看,这里省略了一些不重要的代码:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   

   //... ...

   // Prepare method overrides.
   try {
   
      /**
       * 处理lookup-Method 和replace-Method,统称为overrides
       */
      mbdToUse.prepareMethodOverrides();
   }
   //... ...

   try {
   
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      /**
       * 里面有个后置处理器,如果这个后置处理器能返回一个bean,就直接返回了,不再进行后面的装配,不理会里面的依赖
       * InstantiationAwareBeanPostProcessor
       */
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) 
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值