简单理解Spring getBean流程

本文直接讲述流程,不贴代码,全是干货,面试必看,口口相传。

熟悉Spring启动流程的同学应该清楚,refresh()是最为重要的关键方法,其调用的finishBeanFactoryInitialization(beanFactory)方法则完成了所有非懒加载的单例Bean的实例化和初始化,属性的填充以及解决了循环依赖等问题。

实例化时指将Bean创建出来,初始化是指为bean的属性赋值。

先说一下Bean的创建和管理的一个基本过程, 我们想要获取一个Bean,首先要从我们的bean工厂中获取(注意说的是ObjectFactory),bean工厂则是要去bean仓库中去取,如果仓库中有就直接返回,没有则会创建然后再返回。

SingletonBeanRegistry的实现DefaultSingletonBeanRegistry的属性中便保存着我们的单例对象(三级缓存便在其中)。

代码中创建Bean的过程分为了三步:实例化、填充属性、初始化,分别对应方法createBeanInstance、populateBean和 initializeBean;

之所以和我们前面提过的初始化即是属性赋值有所不同,是因为spring在填充完属性后又执行了一些这个Bean相关的初始化方法。

明白了大致过程后,接下来直接过获取Bean流程:

  • getBean方法在Bean的创建和获取过程中都会用到;另外,我们要注意spring方法起名的特点,有getBean方法,又会有doGetBean方法。同理,后面调用createBean方法,也会调用到doCreateBean方法。
  • getBean后会调用doGetBean方法,第一次调用getSingleton方法先从单例池(一级缓存)中获取;然后当前Bean如果有配置了 depend-on 标签的话,会先去初始化配置的Bean;
  • 紧接着判断是否单例,会第二次调用getSingleton方法,和第一次方法传参不同,多了一个ObjectFactory参数,ObjectFactory是一个函数式接口,有一个抽象方法getObject,而getSingleton的传参是以lamda表达式(即内部实现类)来写的,也就是说,内部类中return的creatBean方法的结果就是ObjectFactory的getObject()返回的值,也就是我们的bean工厂,生成后会保存在一个名叫singleObjects的Map(一级缓存)当中。
  • creatBean调用doCreatBean,接着调用createBeanInstance实例化Bean,主要是为了推断出实例化Bean所需要的构造器,通过反射创建对象;
  • 然后会缓存一些注解元数据信息以及addSingletonFactory方法解决循环依赖问题,此处代码不做重点讲述,面试会直接问循环依赖问题的。
  • 接着执行populateBean方法填充属性,执行两个后置处理器完成自动装配的功能。
  • 接下来会执行initializeBean()方法,该方法中主要会判断执行Aware接口的方法,以及后置处理器的初始化前和初始化后方法等。

好了,虽然以上内容讲解不够详细,但应付面试绰绰有余,想更加详细的理解还是要自己搭建spring本地部署运行起来,一步步地debug,自己加注释,才容易融会贯通。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值