spring bean对象的生成及数据注入的时机 -》getBean

本文详细探讨了Spring中Bean的生成过程,包括预加载和通过`getBean`手动获取。预加载适用于非抽象、单例且非懒加载的Bean。`getBean`接口是关键,涉及BeanFactory的处理,如从单例缓存中查找、FactoryBean的处理等。数据注入主要在`populateBean`方法中完成,通过反射机制设置属性值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家都知道在spring中bean对象的生成分两类一类是预加载,也就是说在容器初始化的时候把bean注入生成的事情一起干了。另一类是需要开发者主动调用getBean来获取bean对象。
1.预加载函数截图如下
在这里插入图片描述通过上面的代码来看,什么样的bean可以被预加载呢?需要满足以下条件:1.不能是抽象类 2.需要是单例 3.懒加载属性值要为false
不管是预加载还是自己手动调用的加载,都是调用getBean 接口来加载bean,所以理解getBean是了解bean IOC的关键,来看个流程图。
在这里插入图片描述1。在这里插入图片描述我们一般使用getBean时候,只传入bean id的名字。

  1. doGetBean
    在这里插入图片描述首先是转换下beanname :1 是不是以&开头,如果是进行相关处理。2 查看是否有别名,如果有返回别名,没有返回自己。
    其次,从单例bean实例对象的hashmap中查找有没有已经存在的bean对象,如果有则返回对象,如果没有继续判断是不是单例工厂(ObjectFactory)子类,如果是则直接调用单例工厂的getObject获取bean对象实例。并把这个对象加入到单例对象haspmap中
    如果返回的Objectc对象如果不为空,则调用getObjectForBeanInstance函数进一步获取bean对象,代码截图如下:
    在这里插入图片描述如果name是以&开头的而且这个类FactoryBean工厂实例则扔出异常。
    如果beanInstance不是FactoryBean类实例或者name是为&开头,则直接返回beaninstance.
    然后从factoryBeanObjectCache 这个map中查找是否已经存在实例
    如果不存在实例,则使用FactoryBean类工厂接口getObject创建一个bean实例,并将它添加到上面说的那个map中去。
    以上部分是针对BeanFactory单例的处理,如果不是工厂单例就要走下面的代码。
    在这里插入图片描述这里会首先判断需要生成的bean对象是不是当前在正创建的,如果是则扔出异常
    如果有父类工厂,则判断这个需要创建的bean是不是已经在父类中生成了。如果是则从父类中找出并返回,getBean结束。如果不是则继续。代码截图如下:在这里插入图片描述
    首先会看这个bean有没有依赖的对象,如果有则先加载其依赖的bean

其次如果这个bean对象是单例,则首先创建单例的类工厂实例(通过createBean创建)。然后再通过工厂类getObject方法获取bean对象(getSingleton),并把这个单例对象加到map中去。最后再调用getObjectForBeanInstance方法,这个方法上面已经有个比较详细的说明了

其它的基本就差不多直接走createBean方法了。其它的函数调用没做过多研究。

7.createBean 在这里插入图片描述这段代码比较简单,就是多了一个resolveBeforeInstantiation函数调用。根据这个代码注释的描述,好像是为proxy类服务的。暂时不用管它。直接看下一个 doCreateBean方式调用

8.doCreateBean在这里插入图片描述先看头部代码。首先看它是不是单例,如果是单例则从之前的cache中获取对象,如果不是或者没成功获取对象则调用createBeanInstance创建一个,这个方法跟踪进去,原理就是通过beanName得到bean的具体类,然后通过JAVA的反射机制使用Constructor类的newInstance方法生成bean类的实例。

一般情况下我们new一个对象后就是调用set函数填充各种属性或者在构造方法里面设置默认值。那个在这里已经生成了Bean对象后,xml里面的属性值填充在哪里做的呢。答案是在populateBean这个方法里面,数据注入是在这里进行的来看下大体流程图在这里插入图片描述populatebean的核心代码截图如下在这里插入图片描述我们知道在xml配置时所有的property属性会被保存在propertyValues类里面(实际上里面使用 map来存储数据),然后对pvs数据进行各种处理,添加,删除,更新等等可能的操作.弄完之后在函数的结尾会调用applyPropertyValues来进行数据注入.
applyPropertyValues主要代码截图如下:在这里插入图片描述大体意思是对pvs里面的所有数据再进行一遍处理,处理完成后.调用用bw.setPropertyValues(new MutablePropertyValues(deepCopy))
这时候就走到BeanWrapperImpl里面了.BeanWrapperImpl是AbstractNestablePropertyAccessor和AbstractPropertyAccessor的子类,我们依次来看调用流程截图如下在这里插入图片描述然后会调到下面这个函数
在这里插入图片描述
然后就是这里了
在这里插入图片描述
然后走processLocalProperty截图如下:
在这里插入图片描述主要看这里的setValue这里就是反射注入了,当然pv.getValue也是方法的反射调用.来看下具体实现在这里插入图片描述好了到这里数据注入完成后,bean对象就是一个可以使用的对象了.大体流程就是这样的啦,很多细节没涉及到,能力有限如有错误敬请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值