Spring源码解读之IOC容器

前言


IOC(Inversion Of Controll,控制反转)是一种设计思想,将原本在程序中手动创建对象的控制权,交由给Spring框架来管理。IOC容器可以看作Spring实现IOC的载体,它实际上就是一个Map,Map中存放的是各种对象,IOC容器就像是一个工厂,当需要创建一个对象,只需要配置好配置文件/注解即可,不用考虑对象是如何被创建出来的,大大增加了项目的可维护性且降低了开发难度。

那么问题来了,IOC底层到底是如何去根据配置文件/注解去实例化Bean的,在实例化之前都做了哪些工作呢,也只有关注源码才能解决问题了。本文是基于Spring5.2.1版本,重点关注基于配置文件的实现方式。

引言

先看启动一个Spring程序的最简单的例子。

抽象类IAccountDao.java

1
2
3
public interface IAccountDao {
void saveAccount();
}

接口实现类AccountDaoImpl.java

1
2
3
4
5
public class AccountDaoImpl implements IAccountDao {
public void saveAccount() {
System.out.println("保存账户成功");
}
}

配置类bean.xml

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="accountDao" class="dao.impl.AccountDaoImpl"></bean>
</beans>

测试类

1
2
3
4
5
6
7
public class test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountDao dao = (IAccountDao) ac.getBean("accountDao");
dao.saveAccount();
}
}

代码很简单,研究源码的话就主要从ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");出发,研究IOC中是如何创建实例Bean的并注入依赖。

先简单看一眼ApplicationContext与ClassPathXmlApplicationContext的类的关系图

ApplicationContext与ClassPathXmlApplicationContext的类的关系图

源码解读

ClassPathXmlApplicationContext.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 构造函数,传入的configLocation为xml配置文件的文件名
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
// 可能会有多个配置文件,处理成数组。
this.setConfigLocations(configLocations);
// 构造函数中的第二个参数就是refresh,一开始默认值为true,当第一次建立ApplicationContext或者后续需要重建的时候就设置true。
if (refresh) {
// 核心的重建方法,后续的分析都是围绕这个函数展开的。
this.refresh();
}
}

进到refresh()中,在AbstractApplicationContext.java

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
public void refresh() throws BeansException, IllegalStateException {
// 加锁,为了线程之间的影响,容易理解。
synchronized(this.startupShutdownMonitor) {
// 设置一些属性:启动时间、closed属性(AtomicBoolean类型,设置为false)、active属性(AtomicBoolean类型,设置为true)
this.prepareRefresh();
// ① 创建Bean容器,初始化BeanFactory,加载并注册Bean
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);

try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}

this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}

}
}

开始拆解refresh()函数的内部

下面会涉及到其他的类,这边借用一张别人的图来说明。我们知道IOC的一个核心就是工厂,也就是这边的BeanFactory的一个系列

BeanFactory相关类图

位置①:refresh()中的ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

类名:AbstractApplicationContext.java

1
2
3
4
5
6
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 通过refreshBeanFactory()函数进行初始化BeanFactory,加载并注册Bean的一系列操作。
this.refreshBeanFactory();
// 返回加载好的BeanFactory
return this.getBeanFactory();
}

进到上面函数的refreshBeanFactory()

类名:AbstractRefreshableApplicationContext.java

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
protected final void refreshBeanFactory() throws BeansException {
// 如果当前ApplicationContext已经加载过BeanFactory,则销毁所有的Bean并关闭
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 初始化一个DefaultListableBeanFactory。那为什么是用DefaultListableBeanFactory来作为Bean Factory呢,可以从最上面的那张类继承图可以看到,DefaultListableBeanFactory是最高级的一层,也就是拥有更多的方法,同时是唯一一个继承了ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory的实现类。
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
// 序列化
beanFactory.setSerializationId(this.getId());
// 重点方法:见下面的那个函数。设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
this.customizeBeanFactory(beanFactory);
// 重点方法:见后面单独列出的代码。加载 Bean 到 BeanFactory 中
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
// 是否允许 Bean 覆盖
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 是否允许循环引用
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}

解释一下何为Bean覆盖和循环引用

Bean覆盖:默认情况下,spring在处理同一个ApplicationContext中名称相同的bean时,分为两种情况处理:

1、如果两个bean是在同一个配置文件中,那么spring会报错。

2、如果是在不同的配置文件中的话,spring会覆盖之前的bean。

循环引用:这个比较好理解,也可以叫做循环依赖,就是A类依赖了B类,B类又依赖A类。具体如何操作可以参看这篇文章

解析xml配置文件

进到 this.loadBeanDefinitions(beanFactory)

类名:AbstractXmlApplicationContext.java

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
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 创建一个beanDefinitionReader对象
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 初始化一些参数
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
// 这块整体是对XML文件的解析
this.loadBeanDefinitions(beanDefinitionReader);
}

// 具体再深入就是将xml文件转换为Document对象,具体调用逻辑比较多,在下段代码总结一下调用流程。
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}

String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
// 调用链路的起点
reader.loadBeanDefinitions(configLocations);
}
}

调用链路

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
// 位置:AbstractBeanDefinitionReader.java
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
String[] var3 = locations;
int var4 = locations.length;

for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
// 标记点
count += this.loadBeanDefinitions(location);
}
return count;
}

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
// 标记点
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}

if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}

return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}

if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}

return count;
}
}
}

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
Resource[] var3 = resources;
int var4 = resources.length;

for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
// 标记点
count += this.loadBeanDefinitions((Resource)resource);
}
return count;
}

//位置:XmlBeanDefinitionReader.java
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}

Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}

if (!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
InputStream inputStream = encodedResource.getResource().getInputStream();

try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 标记点
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if (((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}

}
return var5;
}
}

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
// 将xml文件转化为Document对象
Document doc = this.doLoadDocument(inputSource, resource);
// 标记点
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}

return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
int countBefore = this.getRegistry().getBeanDefinitionCount();
// 标记点
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}

// 位置:DefaultBeanDefinitionDocumentReader.java
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
// 解析xml
this.doRegisterBeanDefinitions(doc.getDocumentElement());
}

protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
// 解析标签
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute("profile");
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
this.preProcessXml(root);
// 总结来说,这边进去就是对大量的标签解析,详细见下面一段代码解析
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}

重点函数解析this.parseBeanDefinitions(root, this.delegate)

位置:DefaultBeanDefinitionDocumentReader.java

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
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();

for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element)node;
if (delegate.isDefaultNamespace(ele)) {
// 解析四类的标签:import、alias、bean和beans
this.parseDefaultElement(ele, delegate);
} else {
// 解析其他标签
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
// 标记点
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析bean标签,返回一个BeanDefinitionHolder对象,具体如何实现见下一段代码。
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {
// 这个是下一节要叙述的内容:注册bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}

那么上面四类的默认标签是如何解析的呢,以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
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 获得bean标签内的id属性
String id = ele.getAttribute("id");
// 获得bean标签内的name属性
String nameAttr = ele.getAttribute("name");
// 将name属性以“逗号、分号、空格”分开,因为我们知道在一个bean标签中可以指定多个name属性,中间的分割方式有三种,这边我们没有设置,所以为null,不进入该段代码。
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}

String beanName = id;
// 如果未指定id,则用name列表,也就是上面产生的aliases的第一个作为id,并把它从列表中移除。
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}

if (containingBean == null) {
this.checkNameUniqueness(beanName, aliases, ele);
}
// 一个<bean></bean>对应一个beanDefinition对象,其中包含了设置bean的一系列信息和解析bean标签内的子元素。
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
// 下面这段是没有生成beanDefinition的处理逻辑,不重要可以不管。
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}

if (this.logger.isTraceEnabled()) {
this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception var9) {
this.error(var9.getMessage(), ele);
return null;
}
}

String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}

上面说到一个bean标签对应着一个beanDefinition,先来看看beanDefinition接口的构成

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
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// bean的作用范围,完全的话是五种,接口中只有单例和多例两种。
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;

void setParentName(@Nullable String var1);

@Nullable
String getParentName();

// bean的全限定名,用于后续的反射生成对象使用。
void setBeanClassName(@Nullable String var1);

@Nullable
String getBeanClassName();
// 设置bean的作用范围,就是之前说的singleton、prototype、request、session、global-session
void setScope(@Nullable String var1);

@Nullable
String getScope();
// 设置是否懒加载(决定了是在何时生成对象)
void setLazyInit(boolean var1);

boolean isLazyInit();
// 设置依赖的bean
void setDependsOn(@Nullable String... var1);

@Nullable
String[] getDependsOn();
//设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效
void setAutowireCandidate(boolean var1);
//该bean是否可以注入到其他bean中
boolean isAutowireCandidate();
//同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
void setPrimary(boolean var1);

boolean isPrimary();
// bean可以通过说静态工厂或实例工厂进行创建。
void setFactoryBeanName(@Nullable String var1);

@Nullable
String getFactoryBeanName();

void setFactoryMethodName(@Nullable String var1);

@Nullable
String getFactoryMethodName();

ConstructorArgumentValues getConstructorArgumentValues();

default boolean hasConstructorArgumentValues() {
return !this.getConstructorArgumentValues().isEmpty();
}

MutablePropertyValues getPropertyValues();

default boolean hasPropertyValues() {
return !this.getPropertyValues().isEmpty();
}

void setInitMethodName(@Nullable String var1);

@Nullable
String getInitMethodName();

void setDestroyMethodName(@Nullable String var1);

@Nullable
String getDestroyMethodName();

void setRole(int var1);

int getRole();

void setDescription(@Nullable String var1);

@Nullable
String getDescription();

ResolvableType getResolvableType();

boolean isSingleton();

boolean isPrototype();

boolean isAbstract();

@Nullable
String getResourceDescription();

@Nullable
BeanDefinition getOriginatingBeanDefinition();
}

到目前位置,走完了xml文件中标签的解析过程,它会解析四类标签(import、alias、bean、beans)。我们以bean为例,解析之后它返回了一个BeanDefinitionHolder对象,其中包含了三类的信息,其一是beanDefinition对象,用于存储bean标签的一些细节,包括各种属性、全限定名等等,是及其重要的一个类,一个bean标签对应着一个beanDefinition对象。其二是beanName,是一个字符串,是解析出来的,一般会是id属性的value。其三是aliases,也就是name属性。

BeanDefinitionHolder对象

注册Bean

先把之前的一段代码拿下来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析bean标签,返回一个BeanDefinitionHolder对象,具体如何实现见下一段代码。
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {
// 这个是下一节要叙述的内容:注册bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}

位置:BeanDefinitionReaderUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
// 关键方法:根据beanName注册bean
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果有别名的话就注册别名,由于这边我们的例子是没有别名的所以忽略。
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;

for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}

}

位置:DefaultListableBeanFactory.java(是不是有点熟悉,没错我们又回到了最顶层的那个beanFactory)

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
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var8) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
}
}
// 之后所有的beanDefinition都会放在这个beanDefinitionMap中,这边判断是否之前存在,进行覆盖(bean的覆盖)。
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
// 如果有重复的beanName,进行覆盖。
if (existingDefinition != null) {
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 这边就是一堆的日志输出,不用管。
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
// 覆盖掉map中原来的beanName即可。
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
// 没有beanName重复的,也就是不需要覆盖的情况进入这边的分支。、
// 如果bean已经开始了初始化(注意,注册的时候还未初始化)
if (this.hasBeanCreationStarted()) {
synchronized(this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
this.removeManualSingletonName(beanName);
}
} else {
// 还没有开始初始化,也就是正常情况下进入的分支。这边将对应的beanName和beanDefinition存入map中。
this.beanDefinitionMap.put(beanName, beanDefinition);
// 保存beanName(String)
this.beanDefinitionNames.add(beanName);
// 将当前的beanName移除手动注册的列表。
this.removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}

if (existingDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}

}

到此位置,注册bean结束,注册bean换句话说就是将beanName和beanDefinition存入beanDefinitionMap中,并且保存对应的一些beanName到List中。

此时,可以返回到最最最开始的refresh()函数了。此时关注到返回的beanFactory中的部分。

beanDefinitionMap


重新将refresh()函数拿过来。

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
public void refresh() throws BeansException, IllegalStateException {
// 加锁,为了线程之间的影响,容易理解。
synchronized(this.startupShutdownMonitor) {
// 设置一些属性:启动时间、closed属性(AtomicBoolean类型,设置为false)、active属性(AtomicBoolean类型,设置为true)
this.prepareRefresh();
// ① 创建Bean容器,初始化BeanFactory,加载并注册Bean。
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 设置beanFactory的类加载器,添加了一些BeanPostProcessor,并且spring会很智能的注册几个特殊的bean
this.prepareBeanFactory(beanFactory);

try {
// bean此时只是加载并注册完成,并没有实现初始化,这步是提供给子类的扩展点,添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事,这边要引入一个知识点:BeanFactoryPostProcessor的作用是来定制和修改BeanFactory的内容,如覆盖或添加属性,是beanFactory的后置处理器。
this.postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor的实现类,这里仅仅是注册,注意区分和BeanFactoryPostProcessor的区别,下面单独列出并解释。这里仅仅是注册,相应方法的回调是在Bean实例化完成之后。
this.registerBeanPostProcessors(beanFactory);
// 初始化当前ApplicationContext的MessageSource
this.initMessageSource();
// 初始化当前ApplicationContext的事件广播器
this.initApplicationEventMulticaster();
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
this.onRefresh();
// 注册监听
this.registerListeners();
// ② 重点方法,初始化所有的单例bean(非懒加载的),下面分析。
this.finishBeanFactoryInitialization(beanFactory);
// ApplicationContext 初始化完成
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}

this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}

}
}

先来解释一下上面提及的BeanFactoryPostProcessorBeanPostProcessor的区别。

BeanFactoryPostProcessor是用于beanFactory的属性处理,可以随意修改beanFactory内所有的beandefinition。是在Bean实例化完成之前回调的。

BeanPostProcessor只能在实例化之后进行调用,主要有两个函数的实现,分别是postProcessBeforeInitializationpostProcessAfterInitialization,分别在bean实例初始化(init-method)之前和之后进行回调,可以看成是对bean的增强。

可以参考这篇文章,文章中提到“网上很多文章都说BeanPostProcessor不能修改bean属性,其实我看来未必,当其实例化之后,完全可以拿到实例化后的对象,对对象进行一些改值操作也完全可以的”,感觉说的也不无道理。文中的例子也能帮助很好的理解,可以一看。


初始化所有的单例bean(非懒加载的)

spring会在这步初始化所有的单例bean(非懒加载的)

位置:AbstractApplicationContext.java

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
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化名字为 conversionService 的 Bean
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}

if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
// 初始化LoadTimeWeaverAware的bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;

for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}

beanFactory.setTempClassLoader((ClassLoader)null);
// 将beanDefinitionNames存到一个String数组中
beanFactory.freezeConfiguration();
// 开始初始化
beanFactory.preInstantiateSingletons();
}

位置:DefaultListableBeanFactory.java

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
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
// 内部保存了所有的beanName
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();

while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();

while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}

return;
}

beanName = (String)var2.next();
// 合并父 Bean 中的配置,和bean的继承相关的东西。
bd = this.getMergedLocalBeanDefinition(beanName);
// 抽象或懒加载或非单例,是不需要初始化的,也就是说不需要执行下面的一些代码,直接在do中操作完之后就return了。
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
// 如果是FactoryBean,会在BeanName前加&,然后再去getBean()初始化bean。
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
// 否则走这里,也就是普通的Bean走这里进行bean的初始化。
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,可忽略不管。
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}

if (isEagerInit) {
this.getBean(beanName);
}
}
}

再来看以下getBean是如何初始化bean的

位置:AbstractBeanFactory.java

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
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException {
return this.doGetBean(name, requiredType, args, false);
}

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
// 这个是返回值,重要。
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}

bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查BeanDefinition在容器中是否存在。
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
// 如果不存在那就要去父容器中找。这边先不管这种情况。
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}

if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}

if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}

return parentBeanFactory.getBean(nameToLookup);
}

if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
// 这边开始终于要创建bean了。
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
// 依赖关系的处理。
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;

for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}

this.registerDependentBean(dep, beanName);

try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
// 如果是单例的,就创建单例的bean。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 关键的创建函数,等下说明。
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 如果是多例的,就创建多例的bean。
var11 = null;

Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
// 同样也是这个函数。
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}

bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 如果既不是单例也不是多例
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}

try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);

Object var4;
try {
// 同样的创建bean。
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}

return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
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", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
// 检查类型。
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}

throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}

上面多次提到的一个方法是createBean()

位置:AbstractAutowireCapableBeanFactory.java

解释一下:这个类看到有Autowire有关,也就是和初始化时候的值的设置相关(涉及到注解的注入方法),也就是可能存在XML和@Autowire这个注解混用的情况。

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
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 之前的代码忽略
......

try {
// 直接来到这个方法
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}

return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}

if (instanceWrapper == null) {
// 一般的bean的实例化方法,很重要。
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}

Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

... // 忽略一部分代码

// 依赖循环问题
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}

this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}

Object exposedObject = bean;

// 这边是bean的初始化,也就是值的装载,因为这个方法里的createBeanInstance()这个函数就已经实例化了bean。
try {
this.populateBean(beanName, mbd, instanceWrapper);
// 关键方法,初始化。这里面还涉及了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);
}

... // 忽略一部分代码。
}

总结一下,这边涉及三个主要的方法,其一是bean的实例化,其二是bean的循环依赖问题的处理,其三是bean的初始化,也就是装配个各种初始值。实例化中重要的函数:createBeanInstance(beanName, mbd, args)。初始化中的重要函数是populateBean(beanName, mbd, instanceWrapper),主要用来一些属性值的注入。初始化完成之后的initializeBean(beanName, exposedObject, mbd)。

bean的实例化过程实现

位置:AbstractAutowireCapableBeanFactory.java

函数:createBeanInstance()

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
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保加载的class
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
// 权限检查
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
// 如果存在 Supplier 回调,则使用给定的回调方法初始化策略
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
// 如果工厂方法不为空,采用工厂方法实例化
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
// 用构造函数进行实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
// 如果已缓存的解析的构造函数或者工厂方法不为空,则我们可以知道它是什么方法进行实例化的,相当于多例bean的情况,第一次实例化是构造函数那么第二次就是构造函数,第一次实例化是工厂方法第二次就是工厂方法。
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// 得到是有参还是无参的构造函数,后续就不需要判断是什么构造函数进行实例化了。
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}

// 已经解析好了是构造函数或者工厂方法
if (resolved) {
// 如果是自动注入,则调用构造函数自动注入构造,否则调用默认构造函数构造
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
// 判断是否采用有参构造函数(判断构造函数的类型是什么,缓存中没有才会进到这段中,需要重新判断,耗时操作)
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
ctors = mbd.getPreferredConstructors();
// 有参构造函数不为空则调用构造函数自动注入构造,否则调用默认构造函数构造
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
// 调用构造函数自动注入构造
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
}

总结上述一段的整体逻辑:

  1. 如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行实例化

  2. 如果存在工厂方法,则使用工厂方法进行实例化

  3. 使用构造函数实例化

    1. 首先要判断缓存,如果缓存中存在,代表已经解析过了,直接使用缓存的实例化方法,这边主要是指无参构造或者有参构造。如果缓存中存在,则resolved=true,直接进入到if判断中。
    2. 若resolved=false,则需要重新判断是有参构造还是无参构造,再用对应实例化方法进行实例化。

再来看具体无参构造或者有参构造的方法是如何实例化出对象,一般来说,应该是通过反射来进行对象的创建,我们拿最简单的无参构造方法instantiateBean(beanName, mbd)来看看。

位置:AbstractAutowireCapableBeanFactory.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(() -> {
return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);
}, this.getAccessControlContext());
} else {
// 实例化
beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 包装并返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}

再进到instantiate()方法中

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
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB
if (!bd.hasMethodOverrides()) {
Constructor constructorToUse;
synchronized(bd.constructorArgumentLock) {
constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}

try {
if (System.getSecurityManager() != null) {
clazz.getClass();
constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
return clazz.getDeclaredConstructor();
});
} else {
constructorToUse = clazz.getDeclaredConstructor();
}

bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Throwable var9) {
throw new BeanInstantiationException(clazz, "No default constructor found", var9);
}
}
}
// 内部使用了反射进行对象的创建(newInstance)
return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
} else {
// 否则用CGLib进行对象的创建
return this.instantiateWithMethodInjection(bd, beanName, owner);
}
}

bean的属性的注入

位置:AbstractAutowireCapableBeanFactory.java

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
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();

while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

// 直接看到这边
if (continueWithPropertyPopulation) {
// 获得所有的属性值
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
this.autowireByName(beanName, mbd, bw, newPvs);
}

if (resolvedAutowireMode == 2) {
// 通过类型注入
this.autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}

Iterator var10 = this.getBeanPostProcessors().iterator();

while(var10.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var10.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}

pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}

pvs = pvsToUse;
}
}
}

if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}

this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}

if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
}

初始化完成后的回调

位置:AbstractAutowireCapableBeanFactory.java

函数:initializeBean()

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
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
// 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
this.invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回调
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}

if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 BeanPostProcessorsAfterInitialization 回调
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

注意,和之前分析BeanFactoryPostProcess和BeanPostProcess一样,BeanFactoryPostProcess的before和after方法分别在init方法(invokeInitMethods)之前和之后。


到此为止,整个IOC的主体流程都应该介绍完毕了。来整体总结一下基于XML的IOC整体流程。

  1. 加载并解析配置文件。
  2. 解析出XML中的bean节点,一个bean对应着一个BeanDefinition对象(该对象会保存我们在Bean节点内配置的所有内容,比如id,name,全限定名,依赖值等等)。
  3. 注册Bean,它将beanName和beanDefinition存入beanDefinitionMap中,并且保存对应的一些beanName到List中。
  4. 根据BeanDefinition实例化所有非懒加载的单例对象。
  5. 依赖注入,初始化完成。
  6. 初始化完成的后置处理。

参考:

https://javadoop.com/post/spring-ioc

https://www.zhihu.com/question/313785621