大家都知道在spring中bean对象的生成分两类一类是预加载,也就是说在容器初始化的时候把bean注入生成的事情一起干了。另一类是需要开发者主动调用getBean来获取bean对象。

1.预加载函数截图如下

bean对象 java bean对象是什么时候注入的_预加载

通过上面的代码来看,什么样的bean可以被预加载呢?需要满足以下条件:1.不能是抽象类 2.需要是单例 3.懒加载属性值要为false

不管是预加载还是自己手动调用的加载,都是调用getBean 接口来加载bean,所以理解getBean是了解bean IOC的关键,来看个流程图。

bean对象 java bean对象是什么时候注入的_spring getbean_02

1。

bean对象 java bean对象是什么时候注入的_bean对象 java_03

我们一般使用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

bean对象 java bean对象是什么时候注入的_spring getbean_04

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

bean对象 java bean对象是什么时候注入的_spring getbean_05

先看头部代码。首先看它是不是单例,如果是单例则从之前的cache中获取对象,如果不是或者没成功获取对象则调用createBeanInstance创建一个,这个方法跟踪进去,原理就是通过beanName得到bean的具体类,然后通过JAVA的反射机制使用Constructor类的newInstance方法生成bean类的实例。一般情况下我们new一个对象后就是调用set函数填充各种属性或者在构造方法里面设置默认值。那个在这里已经生成了Bean对象后,xml里面的属性值填充在哪里做的呢。答案是在populateBean这个方法里面,数据注入是在这里进行的来看下大体流程图

bean对象 java bean对象是什么时候注入的_加载_06

populatebean的核心代码截图如下

bean对象 java bean对象是什么时候注入的_数据_07

我们知道在xml配置时所有的property属性会被保存在propertyValues类里面(实际上里面使用 map来存储数据),然后对pvs数据进行各种处理,添加,删除,更新等等可能的操作.弄完之后在函数的结尾会调用applyPropertyValues来进行数据注入.

applyPropertyValues主要代码截图如下:

bean对象 java bean对象是什么时候注入的_spring getbean_08

大体意思是对pvs里面的所有数据再进行一遍处理,处理完成后.调用用bw.setPropertyValues(new MutablePropertyValues(deepCopy))

这时候就走到BeanWrapperImpl里面了.BeanWrapperImpl是AbstractNestablePropertyAccessor和AbstractPropertyAccessor的子类,我们依次来看调用流程截图如下

bean对象 java bean对象是什么时候注入的_加载_09

然后会调到下面这个函数

bean对象 java bean对象是什么时候注入的_bean对象 java_10


然后就是这里了

bean对象 java bean对象是什么时候注入的_数据_11


然后走processLocalProperty截图如下:

bean对象 java bean对象是什么时候注入的_spring getbean_12

主要看这里的setValue这里就是反射注入了,当然pv.getValue也是方法的反射调用.来看下具体实现

bean对象 java bean对象是什么时候注入的_数据_13

好了到这里数据注入完成后,bean对象就是一个可以使用的对象了.大体流程就是这样的啦,很多细节没涉及到,能力有限如有错误敬请指出