Spring ApplicationContext 中的getBean方法的深入分析

来源:互联网 发布:知乎 胸下夹笔福利 编辑:程序博客网 时间:2024/06/14 07:50

第一章     getBean方法

AbstractApplicationContext中的getBean实际上是调用内部对象DefaultListableFactory中的getBean方法,而DefaultListableFactory中的getBean继承至 AbstractBeanFactory中的getBean 方法。

如图 1-1 可见,getBean实际上都是委托doGetBean方法。


图  1-1

一、      doGetBean方法

a)    如图1-2,首先转换bean的名字,将别名,FactoryBean前缀,去除,结果持有在beanName引用中。

图 1-2

b)    如图1-3, 先从单例Map中获取单例,如果获取成功,调用getObjectForBeanInstance方法获取该对象。此时取出的Object为Bean的FactoryBean对象,调用getObjectForBeanInstance。 如果前缀包含”&”工厂bean前缀,或者本身就已经是bean实例,那么直接返回beanInstance。

图 1-3

 

c)    如图 1-4,如果上一步中未获取到Bean,那么Bean可能尚未生成。那么接下来首先从父工厂中获取Bean,获取Bean定义的合并,检查bean定义合并,获取并注册所依赖的Bean。

图 1-4

d)    创建Bean,此处分为单例Bean创建和原型Bean以及自定义Scope的Bean的创建,具体在后面讲解。

e)    如图 1-5,将Bean强转为要求的类型,转换失败则会报出异常。

 

图 1-5

 

二、      doGetBean方法中创建单例Bean,如图 1-6,  调用的是DefaultSingletonBeanRegistry中的getSingleton(String beanName, ObjectFactorysingletonFactory)方法。

图 1-6

a)    getSingleton方法,如图 1-7所示。

1.    首先获取beanFactory中的singletonObjects中的bean,这是已经创建的。

2.    beforeSingletonCreation,在singletonsCurrentlyInCreation中添加当前Bean定义。

3.    调用singletonFactory的getObject方法,获取单例Bean。

4.    添加此单例Bean到singletonObjects中去。key为BeanName。

图 1-7

b)    getSingleTon实际上调用的还是工厂对象的getObject,而getObject中的方法返回的是createBean,那么让我们进入到createBean中一探究竟。如图1-8,所示,主要完成如下操作:

1.    首先Make sure bean class is actually resolved at this point.保证bean的类型已被加载。

2.    准备方法重写(此处暂且不清楚)。

3.    resolveBeforeInstantiation,这里会给后置处理器偷换bean的机会。

图 1-8

图 1-9

 

c)    doCreateBean方法,如果上一步的bean已经被偷换了,那么不会执行这一步,直接返回到getSingleTon中去了。前五个步骤在图1-10中,后面的在11-12中

1.    先移除缓存中的同名。

2.    创建bean实例。

3.    然后调用合并bean定义的后置处理器。

4.    对与bean定义信息再次加载,以便于后面使用。

5.    暴露bean的EarlyBeanReferenced,主要是为了循环引用,比如a中包含b,b中包含a,这样可以先把引用暴露出来,下面才会调用注入。这里添加一个ObjectFactory作为bean的生产方式,但是返回的只是引用。


图 1-10

6.    populateBean,填充bean中的引用内容,包括注解的字段,spel表达式等等。

7.    调用Bean的初始化方法,init-method,@post-process注解(JSR标准),initializingBean接口,PostProcessor的前,后bean初始化方法等等。

8.    如果允许提前暴露,调用getSingleTon,将完全体的Bean注入到beanFactory中。

图 1-11

9.    如图 1-12,注册Bean的销毁方法。此处包括 destroy-method,还有JSR中的PreDestroy注解等。 然后返回Bean实例

图 1-12

 

d)    populateBean方法。填充bean方法,autoWire, inject等注解就是在此方法中通过调用PostProcessor中的方法设置到bean的依赖中的。下面截取一段该方法中实现注入的代码,如图 1-13,首先判断是根据类型注入还是根据名称注入,然后调用autowireByName或autowireByType方法,将所依赖的类型设置到MutablepropertyValues中,然后调用applyPropertyValues ,将propertyValue应用到BeanWapper中,这里就完成了bean内容的填充。

图 1-13

e)    initializeBean方法,主要完成初始化调用。如图1-14、1-15、1-16所示,有如下步骤

1.    调用beanFactory相关的通知。BeanNameAware、BeanFactoryAware、BeanClassLoaderAware。

2.    调用Bean处理器的初始化前处理。PostConstruct注解就是在此处理。

3.    调用afterPropertiesSet,init-method.

4.    调用Bean处理器的初始化后处理。

图 1-14

图 1-15

图 1-16

 

 

 

三、      创建原型Bean,在创建Bean之前之后,设置正在创建的Bean到一个线程本地变量中,并在创建完成之后移除

a)     

图1-17

图1-18

四、创建自定义Scope的Bean。调用Scope的get方法,传入FactoryBean实例。

     

图1-19

3 0
原创粉丝点击