FactoryBean原理

一、FactoryBean代码

public interface FactoryBean<T> {
//返回的对象实例
    T getObject() throws Exception;
    //Bean的类型
    Class<?> getObjectType();
    //true是单例,false是非单例  在Spring5.0中此方法利用了JDK1.8的新特性变成了default方法,返回true
    boolean isSingleton();

二、FactoryBean作用

1、FactoryBean也是一个bean,通过容器获取bean时getBean()时,对于FactoryBean类型,会调用getObject()方法生成自定义类型的bean。
2、getObject()生成的bean,这个bean的BeanDefination不在容器中,那为什么我们通过容器的getBean()时,为什么有能获得这个bean呢?

 FactoryBeanService bean = applicationContext.getBean(FactoryBeanService.class);
FactoryBeanService bean1 = applicationContext.getBean("factoryBeanLearn", FactoryBeanService.class);
System.out.println(bean==bean1);

三、底层源码

FactoryBean生成的对象保存在factoryBeanObjectCache中
循环Spring容器中所有的beanNames,再根据beanName获取对应的Bean实例,判断获取的Bean实例是不是FactoryBean类型的Bean,如果是,则调用Bean的getObjectType方法获取Class,将获取到的Class和传入的Class进行匹配,如果匹配到,则将此beanName和传入的Class建立一个映射关系。再根据beanName获取到Spring容器中对应的Bean,调用Bean的getObject方法来获取对应的实例。

FactoryBean
1、它也是一个Bean ,也是在Spring容器中,它的创建于其他bean对象没有任何区别。
2、只是在通过容器获取bean的时候,传递的beanName需要在前面加上&,才能正常返回对应的Bean
3、如果只是通过getBean(beanName)的话,获取到的是FactoryBean#getObject()中返回的bean,这个bean也保存在spring容器中,但是与普通的bean保存的位置不同,不是在一级缓存singletonObjects中,而是在factoryBeanObjectCache中。
4、如果想要获取FactoryBean的话,需要在beanName前面加&,才可以,getBean(“&”+beanName)。

底层代码原理

1、 根据beanName获取实例

getBean(BeanName)–>doGetBean()–>getObjectForBeanInstance(sharedInstance, name, beanName, null);–>getObjectFromFactoryBean(factory, beanName, !synthetic);
–> doGetObjectFromFactoryBean(factory, beanName);–>factory.getObject();
1、根部BeanName找到FactoryBean
2、判断beanInstance是否是Factorybean或者beanName 是否以&开头,是的话,直接返回,
3、不是的话,查看factoryBeanObjectCache是否存在实例;
4、doGetObjectFromFactoryBean(),通过FactoryBean#getObject()创建一个beanInstance,并放入到缓存中。

2、 根据BeanType获取实例

getBean(FactoryBeanService.class)–>resolveNamedBean(requiredType, args);–>getBeanNamesForType(requiredType);–>doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);–>isFactoryBean(beanName, mbd);–>isTypeMatch(beanName, type);–>getSingleton(beanName, false);–> getTypeForFactoryBean((FactoryBean<?>) beanInstance);–>factoryBean.getObjectType();–>return new NamedBeanHolder(beanName, getBean(beanName, requiredType, args));

1、遍历BeanName,判断BeanName对应的BeanDefination是否是FactoryBean
2、如果是FactoryBean,然后判断FactoryBean#getObjectType()是否和目标Bean.class是否一致
3、是的话,就返回对应的BeanName,然后根据BeanName返回Bean实例,与通过BeanName获取实例过程一样

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值