如何优雅的回答Spring循环依赖

核心点

  1. spring中Bean的实例化过程是(BeanDefintion)
  2. Bean的生命周期(如果没有这么复杂的生命周期的话,spring循环依赖不存在)
  3. Spring使用三个Map解决循环依赖

详细回答

从spring framework 整个体系而言的话,spring的bean是由BeanDefinition来的,就是我们在Spring当中有个建模的一个类:BeanDefintion,Spring的Ban有一系列复杂的生命周期,…详细的一步步回答生命周期阶段…,(首先Spring容器启动,启动完了之后,会做一个简单的扫描,扫描完了之后把它变成一个BeanDefintion,然后把BeanDefintion保存到BeanDefintionMap中,然后遍历BeanDefintionMap,做一些验证,是否单例,是否原型,是否懒加载等,然后尝试获取这个类有没有已经在单例池中存在,有没有被提前暴露,如果没有提前暴露,spring就会去创建Bean,首先推断构造方法,得到一个最佳的构造方法用来实例化Bean,然后通过反射区实例化一个java对象,再去进行一些初始化工作,是否需要支持循环依赖,如果需要支持循环依赖,那么需要暴露一个ObjectFactory,保存到二级缓存中,然后进行属性注入;再往下执行会执行很多aware接口的回调,执行生命周期接口的回调,@PostConstruct等实现了initializerBean接口的;如果此时判断有AOP的话,会在这个时候生成代理;在往下执行会发布一些事件,此时,生命周期差不多走完了,然后会把这个Bean放到单例池中)。
下面来回答Spring是如何来解决循环依赖的:
Spring在实例化A的时候,首先会对X做一些基本的验证,验证完了之后看下A是否被提前暴露(这个时候还没有提前暴露),推断构造方法,通过构造方法把A实例化出来,此时A会被提前暴露,此时,暴露的是一个由A生成的ObjectFactory对象,一个工厂对象,暴露完了之后代码接着往下执行,会去做X的属性填充,此时发现A依赖了B,此时填充B,但是此时容器中没有存在B,也就是说此时B没有被实例化,他会去做B的生命周期,此时填充B的属性,发现单例池中没有A,然后会去走A的生命周期,判断A是否被提前暴露(如果此时面试官问:为什么要缓存A的ObjectFactory,而不是缓存A的实例化对象:如果我们直接缓存一个A,拿出来的就是A,程序员很难对他做扩展,如果我们暴露的是一个ObjectFactory,由于Spring Framework内部通过BeanPostProcessor这个接口能够对在产生A的过程中,程序员是可以自己去扩展和干预的,所以我们可以得到一个自己想要的对象),此时A已经被提前暴露,完成属性填充。

简单回答:

首先在SpringFramework整个体系中,我们的一个Bean是由一个BeanDefinition来构建的,BeanDefinition相当于SpringBean的一个建模,如果理解循环依赖的话,要先理解Spring的生命周期,大概分为以下几步:首先我们的spring容器启动,做一个扫描,把BeanName变成BeanDefinition,保存到BeanDefinitionMap中,做一个遍历,对我们的Spring这个BeanDefintion做一些基本的验证,是否单例,是否懒加载…,实例化Bean之前,会先去容器中(单例池)获取一遍,查看是否被创建,如果没有被创建,会去二级缓存中查看是否被提前暴露,如果都没有,会去创建X对象,会对X做一些初始化工作,比如填充属性,填充属性过程中,发现X依赖了Y,会走Y的生命周期流程,在实例化Y的过程中,会填充X属性,这是发现X并没有被完整的实例化好,此时会走X的流程,会发现X已经被提前暴露,也就是说他会拿到一个ObjectFactory所产生的一个对象(getobject),此时就完成了循环依赖;

注意:

1,spring循环依赖只支持单例的,因为在spring启动的时候会加载所有的单例Bean,而原型的Bean,只有在使用的时候才会走生命周期流程;
2,循环依赖只支持非构造方法的注入。因为构造方法不能创建对象,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值