spring 5.0.x源码学习系列九: FactoryBean

2021-03-23  本文已影响0人  avengerEug

前言

  1. bean: 通过spring创建,走了spring的bean创建过程
  2. 普通对象: new出来的,未经过spring的bean创建过程

一、项目demo

1.1 项目包结构

在这里插入图片描述

1.2 AppConfig.java

在这里插入图片描述

1.3 BeanA.java

在这里插入图片描述

1.4 Entry.java

在这里插入图片描述

1.5 MyFactoryBean.java

在这里插入图片描述

二、运行结果

在这里插入图片描述

三、原理解析

3.1 要想了解FactoryBean的原理首先得先了解FactoryBean的创建过程

3.1.1 创建FactoryBean入口

在这里插入图片描述

3.1.2 处理bean名称和第一次getSingleton

在这里插入图片描述

3.1.3 创建完FactoryBean

在这里插入图片描述

3.2 从getObjectForBeanInstance方法中获取真正需要的bean

3.2.1 从getObjectForBeanInstance方法中获取普通bean

  1. 类型不是FactoryBean类型的bean
  2. 用户的目的就是想要获取FactoryBean类型的bean
3.2.1.1获取MyFactoryBean情况: context.getBean("&myFactoryBean")
在这里插入图片描述
3.2.1.2 获取MyFactoryBean中维护的bean的情况: context.getBean("myFactoryBean")
在这里插入图片描述
在这里插入图片描述
3.2.1.3 再次获取MyFactoryBean中维护的bean的情况:: context.getBean("myFactoryBean")
  1. 在main方法中新增一行代码

    在这里插入图片描述
    在这里插入图片描述 在这里插入图片描述

四、流程总结

4.1 创建FactoryBean流程

  1. 判断当前创建bean的类型为FactoryBean, 在bean名称前添加&符号
  2. 进入doGetBean方法, 对bean名称前面的&符号进行清除,内部维护了两个bean名称,一个是name另一个是beanName。其中name为真正创建的bean名称,beanName是处理过的bean名称。最终会以beanName去创建bean,所以FactoryBean对应的bean的名称就是首字母小写
  3. 创建完bean后统一走getObjectFromFactoryBean方法。在此方法中有四个参数都比较重要:
    beanInstance: 在doGetBean获取到的bean或者创建出来的bean对象
    name: 要获取真正bean的名称
    beanName: 处理过的bean名称(将name前的&符号去除)
    mbd: 由此参数决定是从缓存中获取bean还是从FactoryBean中调用getObejct方法获取bean
    
    在创建FactoryBean的过程中, 因为name中包含了&符号, 则会在此代码中return, 最终将当前的FactoryBean返回完成bean的创建
    // 在获取的bean跟FactoryBean有关的case下. 前面这个条件永远不会满足,因为首先不管是获取FactoryBean还是FactoryBean维护的bean,从spring单例池中获取的bean一定为FactoryBean。最终再根据实际要获取的bean的名称来决定返回的是FactoryBean还是FactoryBean维护的bean
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
         return beanInstance;
     }
    

4.2 获取FactoryBean流程

4.3 获取FactoryBean维护的bean流程

五、小结

上一篇 下一篇

猜你喜欢

热点阅读