经过IOC的初始化后,定义的Bean信息已经存储到了系统中,但是真正的Bean还没有被加载,通过显式的调用BeanFactory接口中的 getBean方法,才真正的加载并返回可以使用的Bean。

1
2
3
4
5
6
7
8
9
10
//资源定位
ClassPathResource resource = new ClassPathResource("bean.xml");
//bean工厂
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//xml BeanDefinition 阅读器
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
//加载与注册BeanDefinition,完成后的BeanDefinition放置在IOC容器中。
reader.loadBeanDefinitions(resource);
//bean的加载
Object bean = factory.getBean("xxx");

即主要分析getBean(“xxx”)方法。

1
2
3
4
5
@Override
public Object getBean(String name) throws BeansException {
//调用doGetBean
return doGetBean(name, null, null, false);
}

1、doGetBean主流程源码翻译

doGetBean方法代码很长,本篇只分析主流程。

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/**
* 返回指定bean的一个实例,该实例可以是共享的,也可以是独立的。
*
* @param name 要检索的bean的名称
* @param requiredType 要检索的bean的所需类型
* @param args 使用显式参数创建bean实例时要使用的参数
* (仅在创建新实例时应用,而不是检索现有实例时)
* @param typeCheckOnly 是否获取实例用于类型检查,而不是实际使用
* @return bean的实例
* @throws BeansException 如果不能创建bean时抛出
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

// 返回bean名称,在必要时去掉工厂的取消引用前缀,并将别名解析为规范名称。
final String beanName = transformedBeanName(name);
// 最终返回的bean
Object bean;

// 检查单例缓存中手动注册的单例。
Object sharedInstance = getSingleton(beanName);

//单例缓存中存在这个bean
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//指定的单例bean当前是否正在创建(在整个工厂内)。
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//单例缓存中不存在这个bean
else {
//假设我们在一个循环引用中,如果我们已经创建了这个bean实例,则会失败:
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 获取父bean工厂,其用于bean继承支持。
BeanFactory parentBeanFactory = getParentBeanFactory();
// 检查这个工厂中是否存在bean定义。
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 未找到->检查父类。
//确定原始bean名称,将本地定义的别名解析为规范名称。
String nameToLookup = originalBeanName(name);
//如果父bean工厂instanceof AbstractBeanFactory
if (parentBeanFactory instanceof AbstractBeanFactory) {
//从父工厂中获取bean
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// 使用显式args委托给父对象。
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
// 没有args ->委托给标准getBean方法。
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
//以上条件都不满足,直接根据要检索的bean的名称获取
return (T) parentBeanFactory.getBean(nameToLookup);
}
}

// 如果不是仅仅做类型检查则是创建bean,这里需要记录
if (!typeCheckOnly) {
//将指定的bean标记为已经创建(或即将创建)。
markBeanAsCreated(beanName);
}

try {
// 从容器中获取 beanName 相应的 GenericBeanDefinition,并将其转换为 RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

//检查给定的合并bean定义,可能会引发验证异常。
checkMergedBeanDefinition(mbd, beanName, args);

// 保证当前bean所依赖的bean的初始化。
// 返回此bean所依赖的bean名称。
String[] dependsOn = mbd.getDependsOn();
// 如果有依赖
if (dependsOn != null) {
for (String dep : dependsOn) {
//确定指定的依赖bean是否已注册为依赖于给定bean或依赖于其传递依赖项。
//循环依赖的情况
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//为给定bean注册一个依赖bean,在销毁给定bean之前销毁它。
registerDependentBean(dep, beanName);
try {
//获取依赖bean
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

//创建bean实例。
//判断scope是不是"singleton",如果scope为空,也走单例模式。
if (mbd.isSingleton()) {
//返回在给定名称下注册的(原始)单例对象,如果还没有注册,则创建并注册一个新的单例对象。
sharedInstance = getSingleton(beanName, () -> {
try {
//为给定的合并bean定义(和参数)创建bean实例。
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 显式地从单例缓存中删除实例: 它可能是在创建过程中急切地放在那里的,以允许循环引用解析。
//还要删除接收到该bean的临时引用的任何bean
destroySingleton(beanName);
throw ex;
}
});
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//判断scope是否为"prototype"
else if (mbd.isPrototype()) {
// 它是一个原型——>创建一个新实例。
Object prototypeInstance = null;
try {
//原型创建之前的回调。
//默认实现将原型注册为当前正在创建的状态。
beforePrototypeCreation(beanName);
//为给定的合并bean定义(和参数)创建bean实例。
prototypeInstance = createBean(beanName, mbd, args);
} finally {
//原型创建后的回调。
//默认实现将原型标记为不在创建中。
afterPrototypeCreation(beanName);
}
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//request/session/globalsession
else {
String scopeName = mbd.getScope();
//获取 scope 缓存
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// scope 缓存中获取对象
Object scopedInstance = scope.get(beanName, () -> {
//原型创建之前的回调。
//默认实现将原型注册为当前正在创建的状态。
beforePrototypeCreation(beanName);
try {
//为给定的合并bean定义(和参数)创建bean实例。
return createBean(beanName, mbd, args);
} finally {
//原型创建后的回调。
//默认实现将原型标记为不在创建中。
afterPrototypeCreation(beanName);
}
});
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
//在bean创建失败后,对缓存的元数据执行适当的清理。
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// 检查所需类型是否与实际bean实例的类型匹配。
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
//类型转换
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 返回bean
return (T) bean;
}

主要流程:

  • 规范bean名称
  • 尝试从单例模式中获取bean实例
  • 处理单例bean的循环引用
  • 如果容器中没有BeanDefinition,则从父类Bean工厂中获取bean实例
  • 标记指定的Bean为已经创建或者即将创建
  • 注册依赖Bean
  • 根据scope创建bean实例,分为singleton/prototype/request/session/globalsession
  • bean实例类型检查
  • 返回bean实例对象

这个主流程的代码写在:AbstractBeanFactory。
DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory;AbstractAutowireCapableBeanFactory 继承了 AbstractBeanFactory。

1.1、规范bean名称:transformedBeanName(String name)

返回bean名称,在必要时去掉工厂的取消引用前缀,并将别名解析为规范名称。
调用getBean()方法传入的name 不一定就是beanName,可以传入aliasName,FactoryBean,所以这里需要进行转换。

1
2
3
4
5
protected String transformedBeanName(String name) {
//首先:去掉工厂的取消引用前缀"&",如果找到重复的工厂前缀,也要去掉。
//之后:确定原始名称,将别名解析为规范名称。SimpleAliasRegistry中实现。
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

剩下的下一篇分析。

tencent.jpg