第一章 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