Spring中FactoryBean的BeanName解读

最近在学习Spring源码这一块,看到了Spring中的FactoryBean部分,做个笔记加深一下印象和理解。

本章主要将一下beanName&beanName获取到的是啥,以及从哪些容器获取对象

简介

说道FactoryBean肯定会和BeanFactory结合起来。其实也有点见名思意。
FactoryBean : 工厂Bean,这是一个用来创建对象的Bean工厂

BeanFactory : Bean工厂,这玩意啥都有,是一个大的工厂对象。

看源码对BeanFactory的解析:
BeanFactory 生产的对象 由 Spring来控制整个生命周期
在这里插入图片描述

再看FactoryBean
可以由我们自己去管理要创建的Bean对象。
在这里插入图片描述
在这里插入图片描述

结果演示

环境

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="studentFactory" class="entity.StudentFactory">
    </bean>
</beans>

实体类和实体类工厂

// 实现FactoryBean的类
public class StudentFactory implements FactoryBean<Student> {
    public Student getObject() throws Exception {
        return new Student();
    }

    public Class<?> getObjectType() {
        return Student.class;
    }
}

// 实体类
public class Student {
}

Main类

public class FactorybeanTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        StudentFactory factoryBean = (StudentFactory) context.getBean("&studentFactory");
        System.out.println(factoryBean);
        Student studentBean = (Student) context.getBean("studentFactory");
        System.out.println(studentBean);
    }
}

结果
在这里插入图片描述

结论

如果想通过beanName取出FactoryBean对象,必须在beanName前加&符号,否则取出来的是FactoryBean工厂生成的对象

源码分析

1、转变BeanName

通过doGetBean方法进去到容器中去找对应的Bean,会对传入的name进行处理从而得到BeanName
在这里插入图片描述

2、从容器中获取BeanName对应的对象

注意,这里是通过BeanName去获取对象,我们在beans.xml文件中已经配置了StudentFactory这个类,所以这个类肯定是在容器中的,那么肯定能从容器中获取到这个FactoryBean工厂对象。
在这里插入图片描述

3、核心方法getObjectForBeanInstance

既然能获取到FactoyBean对象信息,所以会接着往下走,从Bean实例中获取对象。
在这里插入图片描述
最终进入到父类(org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance)的处理方法。

在这里插入图片描述

4、判断逻辑

1、先判断name是否为空,是否是&开头

如果是name&开头,则进行一些校验后直接返回去了。
在这里插入图片描述
判断的依据通过name是否以&开头

在这里插入图片描述

2、 接下来继续走逻辑,通过BeanName从某个缓存中获取对象

在这里插入图片描述

这个缓存就是factoryBeanObjectCache,先记住后面要用。
在这里插入图片描述

3、如果缓存取不到就进行创建对象处理

在这里插入图片描述

4、创建对象过程

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
真正开始创建Bean对象。
在这里插入图片描述
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
在这里插入图片描述
在这里插入图片描述

5、加入到Bean对象factoryBeanObjectCache容器中

判断Bean容器中是否有对应的FactoryBean,有的话。将该FactoryBean刚才创建的Bean对象加入到factoryBeanObjectCache容器中

在这里插入图片描述

小结

简易流程图简单小结一下
在这里插入图片描述

  • 解析name得到beanName
  • 通过name判断要获取的对象
  • 通过beanName从另一个缓存中获取对象。

DEBUG查看容器对象信息

factoryBeanObjectCache容器

在这里插入图片描述

BeanDefintionMap容器

在这里插入图片描述

一级缓存 singletonObjects 中

在这里插入图片描述

从而我们得知:beanName都是唯一的,在Spring中的一级缓存和BeanDefintionMap中都是存FactoryBean这个工厂类,而另一个缓存容器factoryBeanObjectCache则存放该工厂所生产的对象信息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值