org.springframework.beans.factory.support.AbstractBeanFactory类

org.springframework.beans.factory.support.AbstractBeanFactory

AbstractBeanFactory提供了对Bean的注册和获取、以及对BeanFactory进行配置的各种方法,其中最主要的是getBean()方法:

1
2
3
4
5
public Object getBean(String name) throws BeansException {
//根据Spring一贯的方法命名来看,以do开头的方法才是完成实际功能的方法
//入参分别为:beanName,beanType,对象数组,Bean是否只检查而不创建
return doGetBean(name, null, null, false);
}

(一)doGetBean():加载Bean

  1. 转换对应beanName
  2. 尝试从缓存加载单例
  3. Bean实例化
  4. prototype模式的依赖检查
  5. 检测parentBeanFactory
  6. 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition
  7. 依赖注入
  8. 针对不同的scope进行Bean的创建
  9. 类型转换
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
//入参:
//name:Bean原始名称(可能是别名/FactoryBean)
//requiredType:Bean类型
//args:对象数组
//typeCheckOnly:Bean是否是只检查、不创建的类型
protected<T> T doGetBean(final String name,
final Class<T> requiredType, final Object[] args,
boolean typeCheckOnly) throws BeansException{

//从原始名称中提取对应的beanName
final String beanName = transformedBeanName(name);

Object bean;

//首先检查【缓存】或者【实例工厂】中是否有对应的Bean实例:
//因为创建单例Bean的时候会存在依赖注入的情况,
//而在创建依赖的时候为了避免【循环依赖】,
//Spring创建bean的原则是:
//不等bean创建完成就将创建bean的ObjectFactory工厂提早曝光,
//将ObjectFactory加入缓存,
//一旦下个bean创建时需要依赖上一个bean则直接使用缓存ObjectFactory
Object sharedInstance = getSingleton(beanName);

//Bean已被创建 / 已在缓存中将要被创建
if(sharedInstance != null && args == null){
if(logger.isDebugEnabled()){
//beanName对应的Bean是否正在创建中
if(isSingletonCurrentlyInCreation(beanName)){
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
}else{
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//返回对应的Bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else{
//如果是原型模式,无法解决循环依赖,抛出异常
if(this.isPrototypeCurrentlyInCreation(beanName)){
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中(也即是所有已经加载的类中不包括beanName)
//则尝试从parentBeanFactory中检测
if(parentBeanFactory != null && !containsBeanDefinition(beanName)){
String nameToLookup = originalBeanName(name);
//递归到BeanFactory中寻找
if(args != null){
return (T) parentBeanFactory.getBean(nameToLookup, args);
}else{
return parentBeanFactory.getBean(naemToLookup, requiredType);
}
}
//如果不是仅仅做类型检查,而是创建Bean,需要记录
if(!typeCheckOnly){
markBeanAsCreated(beanName);
}
//将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,
//如果beanName是子Bean的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
//若存在依赖则需要递归实例化依赖的Bean
if(dependsOn != null){
for(String dependsOnBean : dependsOn){\
getBean(dependsOnBean);
//缓存依赖调用
registerDependentBean(dependsOnBean, beanName);
}
}
//实例化依赖的Bean后就可以实例化mbd本身了
//如果是单例模式
if(mbd.isSingleton()){
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>(){
public Object getObject() throws BeansException {
try{
return createBean(beanName, mbd, args);
}catch(BeansException ex){
destorySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//如果是原型模式
else if(mbd.isPrototype()){
Object prrototypeInstance = null;
try{
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}finally{
afterPrototypCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//其他指定的Bean作用域
else{
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if(scope == null){
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try{
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException{
beforePrototypeCreation(beanName);
try{
return createBean(beanName, mdb, args);
}finally{
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}catch(IllegalStateException ex){
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider fefining a scoped proxy for this bean if you intend to refer to it from a singleton", ex);
}
}
}
//检查需要的类型是否符合Bean的实际类型
if(requiredType != null && bean != null
&& !requiredType.isAssignableFrom(bean.getClass())){
try{
retrun getTypeConverter().convertIfNecessary(bean, requiredType);
}catch(TypeMismatchException ex){
if(logger.isDebugEnabled()){
logger.debug("Failded to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) +"]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}

return (T) bean;
}

1.提取Bean名称:transformedBeanName()

  1. 去除FactoryBean的前缀修饰符&
  2. 提取指定别名(alias)所表示的最终beanName
1
2
3
4
5
6
7
8
protected String transformedBeanName(String name) {
//canonicalName():
//获取别名最后指向的beanName
return this.canonicalName(
BeanFactoryUtils.transformedBeanName(name));
//BeanFactoryUtils.transformedBeanName():
//去除FactoryBean的前缀修饰符“&”
}

(1)BeanFactoryUtils.transformedBeanName()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String transformedBeanName(String name) {
//断言非空
Assert.notNull(name, "'name' must not be null");

//这里有个小规范,那就是不要直接操作入参后返回,要用另一个变量保存
String beanName;

//去除beanName中的所有“&”,因为以“&”开头是FactoryBean的修饰符
//比如name = "&value"会变为name = "value"
for(beanName = name; beanName.startsWith("&"); beanName.subString("&".length())){
//不使用1而是使用"&".length()是为了防止魔数出现
}

return beanName;
}

(2)SimpleAliasRegistry#canonicalName()

  • 提取指定别名(alias)所表示的最终beanName
  • 比如别名A指向别名B,别名B指向名为CBean,则返回结果为C
1
2
3
4
5
6
7
8
9
10
11
12
13
public String cononicalName(String name) {
String cononicalName = name;
String resolvedName;
//循环,获取别名对应的最后beanName
do{
//aliasMap:key为别名,value为指向的beanName
resolvedName = (String) this.aliasMap.get(cononicalName);
if(resolvedName != null){
cononicalName = resolvedName;
}
}while(resolvedName != null);
return canonicalName;
}

2.检查单例缓存实例:getSingleton()

  • DefaultSingletonBeanRegistry # getSingleton()
  • Spring会在创建单例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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class DefaultSingletonBeanRegistry 
extends SimpleAliasRegistry implements SingletonBeanRegistry {
//【缓存已加载的单例对象】
private final Map<String, Object> singletonObjects =
new ConcurrentHashMap(256);

//【缓存在Bean创建过程中依赖的其他单例对象,相当于提前暴露】
private final Map<String, Object> earlySingletonObjects =
new HashMap(16);

//【缓存创建Bean的ObjectFactory】
private final Map<String, ObjectFactory<?>> singletonFactories =
new HashMap(16);

//【缓存正在创建中的Bean的名称】
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap(16));

//【beanName对应的Bean是否正在创建中】
public boolean isSingletonCurrentlyInCreation(String beanName){
return this.singletonsCurrentlyInCreation.contains(beanName);
}

//入参:
//beanName:Bean名称
//allowEarlyReference:是否需要从提早曝光的对象缓存中查找,默认为true
//Spring为了避免单例循环依赖,会在Bean尚未创建时,
//就将创建Bean的ObjectFactory工厂提早曝光,所以一般需要先查缓存
protected Object getSingleton(String beanName,boolean allowEarlyReference) {
//首先查询单例对象缓存
Object singletonObject = this.singletonObjects.get(beanName);
//singletonObject == null:无缓存,说明未加载过该Bean
//isSingletonCurrentlyInCreation():说明正在创建中
if(singletonObject == null
&& this.isSingletonCurrentlyInCreation(beanName)){
//虽然用了ConcurrentHashMap,但还是要用额外措施保证互斥性
synchronized(this.singletonObjects){
//判断需要创建的Baen是否在提前曝光的Bean对象中
singletonObject = this.earlySingletonObjects.get(beanName);
//allowEarlyReference:允许从提前曝光的对象中查找
//singletonObject == null:提前曝光对象中没有查到
if(singletonObject == null && allowEarlyReference){
//创建Bean的ObjectFacotry是否已经创建
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
//已创建
if(singletonFactory != null){
//获取Bean
singletonObject = singletonFactory.getObject();
//Bean加入提前曝光的Bean缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//移除对应的ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
}
}

3.获取Bean实例:getObjectForBeanInstance()

  • 缓存中记录的只是最原始的Bean状态,不一定是我们最终想要的Bean —— 比如我们需要对FactoryBean进行处理,但是缓存中得到的只是FactoryBean的初始状态,但是我们真正需要的是FactoryBean中定义的factory-method方法中返回的Bean
  • getObjectForBeanInstance()就是获取实际的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
//入参:
//beanInstance:Bean实例
//name:原始名称(可能是别名/FactoryBean)
//beanName:解析出来的beanName
//mbd:可合并的BeanDefinition
protected Object getObjectForBeanInstance(Object beanInstance,
String name, String beanName, RootBeanDefinition mbd){
//BeanFactoryUtils.isFactoryDereference():
//是以“&”为前缀的FactoryBean
//如果是FactoryBean的格式,但又不是FactoryBean,抛出异常
if(BeanFactoryUtils.isFactroyDereference(name)
&& !(beanInstance instanceof FactoryBean)){
throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
}
//如果是FactoryBean实例,但不是FactoryBean的格式
else if(beanInstance instanceof FactoryBean
&& !BeanFactoryUtils.isFactroyDereference(name)){
Object object = null;
if(mbd == null){
//查FactoryBean缓存
object = this.getCachedObjectForFactoryBean(beanName);
//缓存中没有,则用beanInstance强转创建
if(object == null){
//强转,创建FactoryBean
FactoryBean<?> factory = (FactoryBean)beanInstance;
//BeanDefinition已经加载
if(mbd == null && this.containsBeanDefinition(beanName)){
//合成
mbd = this.getMergedLocalLocalBeanDefinition(beanName);
}
//是否是合成的
boolean synthetic = mbd != null && mbd.isSynthetic();
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
}
return object;
}else{
return beanInstance;
}
}

(1)BeanFactoryUtils.isFactoryDereference()

  • 判断入参是否是以&开头的非空字符串(即是否是FactoryBean
1
2
3
public static boolean isFactoryDereference(String name){
return name != null && name.startsWith("&");
}

(2)FactoryBeanRegistrySupport # getCachedObjectForFactoryBean()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{
//【FactoryBean对象缓存】
private final Map<String, Object> factoryBeanObjectCache =
new ConcurrentHashMap(16);

//【常量:空对象】
protected static final Object NULL_OBJECT = new Object();

protected Object getCachedObjectForFactoryBean(String beanName){
//查FactoryBean缓存
Object object = this.factoryBeanObjectCache.get(beanName);
return object != NULL_OBJECT ? object : null;
}
}
-------------本文结束感谢您的阅读-------------

本文标题:org.springframework.beans.factory.support.AbstractBeanFactory类

文章作者:DragonBaby308

发布时间:2019年10月22日 - 23:06

最后更新:2019年10月24日 - 22:35

原始链接:http://www.dragonbaby308.com/org-springframework-beans-factory-support-AbstractBeanFactory/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%