另一篇 Bean加载流程梳理之BeanDefinitions加载,分析了Spring上下文加载的代码入口及BeanDefinitions加载流程的梳理。在AbstractApplicationContext的refresh方法中,首先获取了ConfigurableListableBeanFactory
类型的beanFactory,然后对beanFactory进行了一系列的设置及其他资源的设置。一切准备就绪后,使用了finishBeanFactoryInitialization
方法完成了对于所有非懒加载的Bean的初始化。
finishBeanFactoryInitialization源码
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
功能讲解:
finishBeanFactoryInitialization方法中调用了DefaultListableBeanFactory的preInstantiateSingletons
方法,本文针对preInstantiateSingletons进行分析,解读一下Spring是如何初始化Bean实例对象出来的。
preInstantiateSingletons源码
1 | public void preInstantiateSingletons() throws BeansException { |
doGetBean源码
由源码可知,获取Bean对象实例,都是通过getBean方法,getBean方法最终调用的是DefaultListableBeanFactory的父类AbstractBeanFactory类的doGetBean方法,因此这部分重点分析一下doGetBean方法是如何构造出一个单例的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
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
131protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = this.transformedBeanName(name);
/**
* 首先检查一下本地的单例缓存是否已经加载过Bean,
* 没有的话再检查earlySingleton缓存是否已经加载过Bean,
* 有的话执行后面的逻辑。
*/
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if(sharedInstance != null && args == null) {
if(this.logger.isDebugEnabled()) {
if(this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if(this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory ex = this.getParentBeanFactory();
if(ex != null && !this.containsBeanDefinition(beanName)) {
String var24 = this.originalBeanName(name);
if(args != null) {
return ex.getBean(var24, args);
}
return ex.getBean(var24, requiredType);
}
if(!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(ex1, beanName, args);
//处理bean的依赖类。depends-on依赖的Bean会优先于当前Bean被加载
String[] dependsOn = ex1.getDependsOn();
String[] scopeName;
if(dependsOn != null) {
scopeName = dependsOn;
int scope = dependsOn.length;
for(int ex2 = 0; ex2 < scope; ++ex2) {
String dep = scopeName[ex2];
if(this.isDependent(beanName, dep)) {
throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dep + "\'");
}
this.registerDependentBean(dep, beanName);
this.getBean(dep);
}
}
if(ex1.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, ex1, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
} else if(ex1.isPrototype()) {
scopeName = null;
Object var25;
try {
this.beforePrototypeCreation(beanName);
var25 = this.createBean(beanName, ex1, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
} else {
String var26 = ex1.getScope();
Scope var27 = (Scope)this.scopes.get(var26);
if(var27 == null) {
throw new IllegalStateException("No Scope registered for scope name \'" + var26 + "\'");
}
try {
Object var28 = var27.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
//调用AbstractBeanFactory类的createBean方法获取bean
var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' 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", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}
if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean \'" + name + "\' to required type \'" + ClassUtils.getQualifiedName(requiredType) + "\'", var22);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
功能分析:
上述代码是获取单例bean
的处理流程,程序会先从本地的单例缓存中获取,如果没有,再去加载单例bean的时候,如果该bean依赖其他bean,则先加载所依赖的其他bean,最后再去调用AbstractAutowireCapableBeanFactory
类中的createBean方法。
doCreateBean源码
从AbstractAutowireCapableBeanFactory
类中的createBean方法,追溯到doCreateBean
方法,该方法为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
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
90protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
//初始化bean
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if(instanceWrapper == null) {
//创建出Bean的实例,并包装为BeanWrapper
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
mbd.resolvedTargetType = beanType;
Object earlySingletonExposure = mbd.postProcessingLock;
//Allow post-processors to modify the merged bean definition.
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean var20 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(var20) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//Initialize the bean instance.
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
if(exposedObject != null) {
//此语句执行,在bean的实例化过程中对bean做一些包装处理。(即:BeanPostProcessor接口)
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var18) {
if(var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if(var20) {
Object ex = this.getSingleton(beanName, false);
if(ex != null) {
if(exposedObject == bean) {
exposedObject = ex;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if(!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name \'" + beanName + "\' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using \'getBeanNamesOfType\' with the \'allowEagerInit\' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
功能分析:
该方法先获取BeanWrapper对象,然后在加载bean之前,然后在bean的实例化过程中对bean做一些包装处理,即执行BeanPostProcessor
接口子类相关逻辑和若bean继承了InitializingBean,则执行afterPropertiesSet()方法。
createBeanInstance部分关键源码
1 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { |
instantiateBean源码
默认构造函数,使用setter注入属性,执行此段代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object ex;
if(System.getSecurityManager() != null) {
ex = AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this);
}
}, this.getAccessControlContext());
} else {
ex = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapperImpl bw = new BeanWrapperImpl(ex);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}
1 | public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { |
1 | public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { |
功能分析:
通过反射生成Bean的实例。看到前面有一步makeAccessible,这意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造
。
最后注意一下,这里被实例化出来的Bean并不会直接返回,而是会被包装为BeanWrapper继续在后面使用。
populateBean源码
该源码实现了bean的属性注入。
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { |
applyPropertyValues源码
1 | protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { |
功能分析:
该方法的主要功能是实现bean内属性的转换,因为在解析beanDefinition时,属性都是以String类型存储的,因此需要类型转换。String中内置的类型转换类有:ByteArrayPropertyEditor, ClassEditor, CustomBooleanEditor, CustomCollectionEditor等,需要深入了解,可以学习Spring官网 Validation, Data Binding, and Type Conversion
initializeBean源码
1 | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { |
功能分析:
我们得知,在invokeInitMethods的执行前后,spring会分别调用所有的BeanPostProcessor,执行其中的方法。invokeInitMethods方法主要作用有两个:
判断bean是否继承了InitializingBean,如果继承接口,执行afterPropertiesSet()方法,
获得是否设置了init-method属性,如果设置了,就执行设置的方法
invokeInitMethods源码
1 | protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { |
整个bean加载顺序图: