Spring源码学习--bean加载之bean的实例化

加载过程有一个高频率使用的方法,getObjectForBeanInstance(),无论是从缓存中获取bean还是根据不同的scope策略加载bean,得到的bean都要调用该方法检测正确性,其实就是检测当前bean是否是FactoryBean,如果是那么需要调用FactoryBean实例中的getObject()获得真正想要的bean.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

// Don't let calling code try to dereference the factory if the bean isn't a factory.
//如果指定的name 是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型则检测不通过
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}

/*
*现在我们有了一个bean的实例,这个实例可能是正常bean或者是FactoryBean
*如果FactoryBean 我们使用它创建实例,但是如果用户想要直接获取工厂实例
 *而不是工厂的getObject方法对应的实例那么传入name应该加入前缀 &
*/
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}

//加载Factory
Object object = null;
if (mbd == null) {
//从缓冲中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
//将存储在xml配置文件的GernericBeanDefinition转换为RootBeanDefinition.
// 如果指定的beanName 是子Bean的话同时会合并父类的相关属性.
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的,而不是应用程序本身定义的.
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从Factory中解析bean的工作交给 getObjectFromFactoryBean***
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
0%