美文网首页
【Spring源码】 FactoryBean接口

【Spring源码】 FactoryBean接口

作者: 天还下着毛毛雨 | 来源:发表于2020-12-30 17:34 被阅读0次

    容器初始化阶段 实例化原始bean

    启动容器的时候,如果当前bean 实现了FactoryBean,则先实例化将name改成(&original),beanName=original,将BD.isFactoryBean改为true,先实例化的也是原生bean,单例池存的就是
    {original(beanName),@Original(原实例)},

    先给name加个前缀 &

    image

    beanName会去除&,但是name还是&开头的

    image

    先实例化原始bean,beanName作为一级缓存的key

    image

    最后尝试替换成getObject,但是发现是&符号开头,且为FactoryBean类型,则不调用getObject方法,返回原始实例

    image

    如果手动调用getBean("&original"),和上面的流程是一样的,只不过可能是从缓存中先取出原始bean

    getBean("original")

    getObject的实例在启动阶段不会被实例化,必须得等到getBean("original")的时候再实例化,
    SmartFactoryBean 如果实现的是这个接口,并且重写的isEagerInit()返回的是true,提前触发getObject

    image

    根据原始bean的beanName,先从缓存中取出原实例(原实例在容器初始化阶段就已实例化)

    image

    如果name 是 & 开头的,则返回原实例

    image

    是否是FactoryBean类型,不是的话直接返回

    image

    是的话往下走, 先FactoryBean的缓存factoryBeanObjectCache中拿getObject()返回的bean,拿不到调用原实例的getObject

    image

    调用原实例的getObject

    image image

    最后加入把替换成getObject()返回实例 加入factoryBeanObjectCache缓存中

    image

    总结:

    1. 实现FactoryBean接口的bean会创建两个对象,一个是原始bean,一个是FactoryBean的getObject()返回的bean
    2. 原始bean在容器refresh的阶段就会创建,并且会放入一级缓存中,key为无&的名称,由于这个阶段在容器调用getBean的时候,会由于它是FactoryBean类型,给他的name加上&,所以实例化后的替换阶段会直接返回原实例,不会触发getObject
    3. 触发getObject一般不会在refresh阶段,需要你手动调用getBean("原始bean名称"),除非你实现SmartFactoryBean接口,并且重写isEagerInit()返回true
    4. 触发getObject()会返回一个新对象,并且有一个专门存放这种bean的缓存factoryBeanObjectCache,{原始bean名称 :getObject返回的实例}

    相关文章

      网友评论

          本文标题:【Spring源码】 FactoryBean接口

          本文链接:https://www.haomeiwen.com/subject/mjghoktx.html