Spring中doGetBean方法详解
doGetBean方法开始会调用getsingleton()方法尝试获取bean实例,如果该bean实例为空,则继续执行下面的代码。如果bean实例不为空,则调用getObjectForBeanInstance()方法。获取Bean 实例。
这里提到的的实例不为空我解释一下,当使用applicationcontext的实现类或者是beanfactory来加载bean.xml文件(或者是application.xml文件,总之是用xml的形式将某个类加入到spring应用上下文中),有可能会采用非延迟加载的形式。而非延迟加载就意味着某个bean在applicationcontext的实现类调用getbean方法之前(applicationcontext的实现类加载bean.xml文件之后),bean就已经实例化了。
然后呢这里的getobjectfromfactorybean存在的意义在于,
从缓存中得到了bean是原始状态,并不一定是我们最终想要的bean。需要对bean进行实例化。我们需要对工厂bean进行处理,我们真正需要的是工程bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。getObjectForBeanInstance最终调用Factorybean中的getobject()方法。其实如果我们对xml中的bean进行实例化,可以在xml的factory-method中声明一个自定义类,然后该类需要实现factorybean中的getobject方法,所以说factorybean就是负责将spring应用上下文中的bean进行实例化的。
getObjectForBeanInstance()方法中,通过源码可知,如果当前 Bean的类型是FactoryBean,则在getBean时不是直接返回 当前 Bean实例,而是先获取Bean实例,然后调用其工厂方法
然后在getobjectfromfactorybean中调用
Dogetobjectfromfactorybean中调用
Factorybean中的getobject()方法。
如果Bean实例为空,上述所有代码就不会执行,而是执行接下来的代码,接下来的代码会去获取当前bean工厂的父工厂,这里是递归的获取父工厂 ,知道获取了当前bean工厂的祖先工厂。
我放上我所做的两个项目的不同版本的dogetbean方法做一个对比。
我认为前者比较好理解,若ParentBeanFactory不为空且beanDefinitionMap中没有这个bean,则调用 ParentBeanFactory的getbean()方法。
若ParentBeanFactory为空或者beanDefinitionMap中有这个bean,则执行接下来的代码。
接下来的getbean()方法用于解决当前bean所依赖的其他bean的实例化。
然后就是几个if判断,用于判断当前bean的scope,诸如singleton,prototype,session和request之类的。
这里是对于singleton类型的bean所做的处理。
对于singleton类型的bean,
new ObjectFactory<Object>()是接口式的匿名内部类(java中有三种匿名内部类的方式)
重写了getObject()方法,里面调用了createbean()
这里的createBean()方法,是AbstractAutowiredCapableBeanFactory中的createBean(),
Createbean调用的第一个方法是
第二个方法
第三个方法
关于doCreateBean()方法,
他调用的第一个方法是
该方法里面利用ConstutorResolver类中的autowireconstructor()完成了构造方法的注入。
然后调用
Populatebean使用bean定义中的属性值填充给定BeanWrapper中的bean实例
initializeBean负责初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器
以后再补充。