Spring的Bean存储探讨

上文猜想Bean在Spring存储,这篇文章就带着之前的猜想,进入源码中一一验证。
上文猜想
源码编译

如何找到Spring存储的容器

不知道你是否使用过操作Spring容器的工具类,在一些非SpringBean的对象里面,要使用Bean对象时,就没办法使用@Resource或者@Authorware注解注入。这是就需要使用SpringUtils.getBean(Clazz.class)来获取Bean对象。比如:(可以随便找一个,可能看到的实现类不相同,但是继续往里面看一点是一样的(容器肯定是同一个)))

1、从日常使用找到入口

在这里插入图片描述

2、ConfigurationListableBeanFactory

既然我们这里使用到的是ConfigurationListableBeanFactory,那我们就从这个里面分析。
在这里插入图片描述
从beanFactory.getBean(name)进去之前,你会发现进入到了BeanFactory接口,作为Bean的工厂,那是不是Bean的创建、存储、使用都是由这个来控制呢?
那我们接着看BeanFactory的实现类(看这个的实现类你会发现非常多,如果是第一次接触Spring源码的建议先找些视频学习下)。根据我们的经验,我们可以进入到ConfigurationListableBeanFactory接口查看实现类,getBean方法的实现肯定在对应某个实现类里面。
在这里插入图片描述
这样我们就找到了DefaultListableBeanFactory。既然找到了入口,那么接下来就是进入源码中的(但是不要忘记我们的任务,当前只是为了找寻对应容器而已,不要陷入其他逻辑中,不然很容易晕车-从入门到放弃)。

3、DefaultListableBeanFactory

第一个,我们进入到了DefaultListableBeanFactory中,查看对应的getBean方法。
在这里插入图片描述

4、DefaultListableBeanFactory.resolveBean()

这个没啥特殊的,方法里面很简单,然后就来到了resolveBean方法:这个方法咋一眼看,一脸懵逼,其实你看它的return,在结合Spring只有一个容器,我们随便找一个应该都能找到容器。
在这里插入图片描述
我们就选第一个return方法进入查看:这里面就主要三段代码,三段代码都和candidateNames有关。

String[] candidateNames = getBeanNamesForType(requiredType);

看这段代码,意思也非常明确:根据类型获取Bean的名称。那么并没有获取到真正的Bean对象。继续想办法找。
在这里插入图片描述
从return找到关键信息,找到getBean方法才是获取一个实例对象,然后返回:
在这里插入图片描述

5、AbstractBeanFactory.getBean()

在这里插入图片描述
接着看doGetBean(我这里的代码收起来了,只展示了一些关键逻辑):重点在getSingleton:获取单例的Bean
在这里插入图片描述

6、DefaultSingletonBeanRegistry.getSingleton():

在这里插入图片描述
我们先不分析这段代码逻辑,可以看到最后的bean对象是从singletonObjects、earlySingletonObjects、singletonFactories这里面取出来的。说明最终的Bean是存储在这些里面。那么跟我们之前的猜想基本一致,以Map的形势存储在内存当中。那么到这里关于Bean存储的猜想和验证基本上就结束了。
在这里插入图片描述
这里其实就是常常说的Spring的三级缓存,以及如何解决循环依赖问题的主要逻辑。我们后续在详细分析。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值