spring ioc简版

文章详细阐述了Spring框架中IOC容器创建bean的过程,包括从refresh方法开始,预实例化单例,通过BeanUtils创建实例,处理构造器依赖,解决循环依赖机制,特别是@Autowired注解的处理和属性填充。在这一过程中,涉及到了Spring的三级缓存机制,确保bean的正确初始化和依赖注入。

化繁去简,梳理IOC核心脉络

  1. 入口:bean的创建
    进入 refresh 方法 -》 preInstantiateSingletons
    遍历了 beanDefinitionNames,并根据 beanName 进行了 getBean
    doGetBean -》 getSingleton -》 createBean
    resolveBeforeInstantiation 为对象创建代理对象
    doCreateBean - 》 BeanWrapper createBeanInstance
    -》 instantiateBean(beanName, mbd);
    -》 instantiate 首先获取了当前这个类的构造器, 通过
    BeanUtils.instantiateClass(constructorToUse) 返回实例
    -》 ctor.newInstance

实例已经创建了,但是属性值还没有,先判断早期的 bean 暴露出来,如果有循环依赖, 调addSingletonFactory 把bean 加入到 spring 的第三级缓存

  1. 填充属性,此处解决循环依赖
    populateBean 设置属性
    循环遍历 BeanPostProcessor , 其中有
    AutowiredAnnotationBeanPostProcessor,就是处理我们 @Autowired 注解的类
    进入bp.postProcessProperties
    里面首先获取了当前类中以 @Autowried 注解的属性,然后开始注入
    inject 方法内部,循环遍历需要注入的属性进行注入,
    AutowiredFieldElement. inject() 再进入resolveFieldValue
    首先调resolveDependency() 处理了依赖关系, 进入doResolveDependency里面调用 descriptor 的 resolveCandidate方法, 就看到了我们非常熟悉的方法了:beanFactory.getBean(beanName)

  2. 接下来循环依赖
    先记住三级缓存
    一级缓存 singletonObjects 中存放完全初始化好的 bean 的实例。
    二级缓存 earlySingletonObjects 中存放早期对象(未完全初始化完成的 bean 实例)。
    三级缓存 singletonFactories 中存放 bean 工厂对象。
    假设刚刚实例化的是payServicelmpl这个bean,初始化读到属性userservice,然后就开始实例化userservicelmpl这个bean,继续走一遍getbean流程。到populateBean设置属性时,它有个payservice,重复前面的流程到beanFactory.getBean
    先进入getSingleton,前面在创建payServicelmpl这个bean时,初始化还没完成,所以从singletonObjects取的是null,但是isSingletonCurrentlyInCreation是true,
    allowEarlyReference也是true,就可以到singletonFactories里面取,就呼应了
    populateBean前addSingletonFactory这个方法。
    然后将它存到二级缓存 earlySingletonObjects 中,并删除三级缓存中的当前 bean
    此时,回到 doGetBean 中,这次获取到的 sharedInstance 就不是空了
    接下去执行 getObjectForBeanInstance, 如果不是 FactoryBean,这里面直接就返回当前实例 。
    再回到 用 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties 方法的地方,现在发现 userServiceImpl 中的 属性已经设置好了,到这边为止,userServiceImpl 的 populateBean 就执行完毕了
    然后调用 exposedObject = initializeBean(beanName, exposedObject, mbd); 进行最后的初始化并暴露此 bean
    最后,返回已经初始化完成的 bean
    然后,一层层退出,最终回到给最初的 payServiceImpl 设置属性的地方
    获取到完整的 bean 之后,会将此 bean 实例加入到一级缓存
    getSingleton(String beanName, ObjectFactory<?> singletonFactory ) --> addSingleton(beanName, singletonObject);

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值