概述

工作过程中断断续续的有使用过spring、spring boot框架,平时接触的最多的也是这些,但是由于平时更多的是 使用到这些东西,因此对于原理没有深究,不过随着使用的深入,发现还是有必要了解一些原理性的东西,不然平时 听别人吹逼的时候你只能抓瞎,就问你慌不慌?(当然也有些公司基于spring开发了自己的一套框架,因此源码的学习 还真的不是吹逼就完事了的)

关于spring的介绍,接下来我会分成多个模块来分别总结,本小结主要是针对spring的IOC机制来讲解。 IOC全称叫做inversion of control,翻译过来就叫做控制反转,我们平时说的DI(dependency injection:依赖注入) 可以认为是控制IOC的具体实现,因此当别人提到spring的IOC和DI的时候,我们可以将其理解为是同一种模式,这种模式的 特点是当我们构造一个对象的时候,该对象所需的依赖都由一个controller传进去,这种机制也就解释了控制反转的意义, 将自身对象生成的权限由自身移交给另外一个控制器,控制反转带来的好处就是解耦合,被创建的对象本身并不需要关心 自身的依赖,只需要将依赖设置成接口即可,这样就可以在装配的时候由控制器传入不同的实现,从而快速的切换业务线。

启动过程分析

构建demo

接下来我们先构建一个spring的工程,然后通过断点调试来一步步讲解IOC的流程,项目整体结构如下: 由于本文主要是解析IOC的机制,因此所需的依赖只有spring-context,没有必要把杂七杂八的依赖都引入下来

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>

然后我们在resource目录下新建一个application-context.xml的文件,具体内容如下:

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

<bean id="hello" class="com.web.HelloService"/>
</beans>

接下来我们构建工程所需要的类HelloService、WorldService,内容分别如下:

1
2
3
4
5
6
7
8
9
import org.springframework.beans.factory.annotation.Autowired;

public class HelloService {


public void syaHello() {
System.out.println("hello " + worldService.world() + " !");
}
}

最后我们新建一个MainService用来测试当前的工程,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainService {

public static void main(String[] args) {
// 容器实例化
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
// bean实例化
HelloService helloService = (HelloService) context.getBean("hello");
helloService.syaHello();
}
}

最后我们从控制台看到了hello !,整个过程就是这么简单(不过这个过程可是真不简单),可能我们忍不住想问一下,IOC在哪里体现出来呢?

答案就在上面的context.getBean(“hello”);这一行,这里的context可以理解为一个controller,我们想要什么对象就跟其进行申请即可。 多说一句我们在看Spring相关源码的时候经常会看到各种context,也就是各种上下文,起初的时候我是经常会被绕晕,后来就慢慢发现 所谓的上下文可以理解为一个持有指定范围的公共变量的容器,比如我们在上面看到的ApplicationContext就可以认为是持有整个应用的 公共变量,因为持有的是整个应用的公共变量,因此这些变量在整个应用中都是可以共享的,这么说是不是就明白了。

接下来我们会针对上面的代码进行分析,整个分析过程也会分成两部分:

  • 容器的实例化
  • bean的实例化

容器的实例化

在进入看具体的代码前,我们先来概要的说一下什么是容器,并从主观的角度去考虑一下,如果是我们自己来写框架的话,我们要注意什么。

说到容器我们最先想到的可能就是水杯之类的东西,那么他的主要的作用是什么呢?应该是holder住一些东西吧。嗯,我们在spring里面提到 的容器大致的作用也是如此,用来存放一些资源,或者更准确的说是存放一些对象!那么为什么要存放这些对象呢?我们平时写代码,只管 new一个对象,剩下的回收工作都交给JVM去操作了,这一切看起来都很合理,缓存对象带来的好处就是减少new一个对象和回收一个对象所带来的 开销。

那么有没有什么不太适合这种缓存对象场景的呢?那肯定也是有的,比如说我们生成了一个包含状态的对象,那么一旦我们缓存了这个对象 之后,后面再使用这个对象就会发现已经是一个脏的对象了(这里的脏表示缓存的对象已经缓存了上次调用的信息),因此,缓存一个有状态的 对象显然不是一个好的选择,这也是我们在spring中通常都使用singleton的原因。 相信很多人在spring的工程中使用httpclient都会记得,我们在声明这种类型的java bean的时候我们通常都会指定prototype,指定为prototype的 作用就是当我们再次需要这种类型的对象的时候,会直接生成一个新的对象,并不会复用之前的对象。

言归正传,我们接下来看一下容器的创建创建过程吧:

1
2
3
4
5
6
7
8
9
10
11
12
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {

super(parent);
// 这里的configLocations是我们传进来的application-context.xml,
// 因为默认会去classpath下去寻找对应的文件,所以我们不用在意是不是传了绝对路径或者相对路径,总之肯定是可以找到对应的文件的
setConfigLocations(configLocations);
if (refresh) {
// 核心方法,我们接下来的讲解也是针对这个方法的分析
refresh();
}
}

下面我们会针对refresh这个方法进行分析,不过在分析之前我们还需要做足一下功课,梳理一下容器的继承关系, 不然这么多东西还是啃不动。 一眼看去真的是眼花缭乱,本来以为就创建个容器,一下子冒出来这么多东西,也真是没谁了。不过我们也用不着害怕,我们只需要知道 一些关键的东西就可以了。需要注意的是,虽然我们在项目中看到了这么复杂的继承关系,不过ApplicationContext并不应该理解为 BeanFactory的实现类(虽然继承关系上来看是这么回事),而是ApplicationContext内部会持有一个beanFactory,我们所有的 和beanFactory调用相关的都是会通过内部持有的beanFactory来进行调用(从这里来看ApplicationContext更像是BeanFactory的 一个代理),这个beanFactory类型是DefaultListableBeanFactory,其类关系图如下: 另外值得一说的是,不要看某一个类实现了这么多的接口就抓瞎了,接口本身是提供了方法的声明,所以其实是增加了操作某一个对象的方式。 因此一个类继承的接口越多,则从侧面说明该类的功能越齐全,这也是为什么ApplicationContext内部会持有一个DefaultListableBeanFactory 了,功能强大呗。

说了这么多,我们看一下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
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
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备工作:记录容器的启动时间并标记容器已经启动
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// 这一步比较关键,主要是将bean的配置文件解析成一个个的beanDefinition,
// 并构建一个beanName->beanDefinition的map用于快速查找文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// 这一步主要是设置bean类加载器,这一点可能会在多个容器之间传递实例的时候会用到(mark一下)
// 注册一些BeanPostProcessor,这些bean主要是应该会针对性的增强对应的bean(并不是为自身
// 的增强做准备),有点类似于责任链的功能了,只不过初始的时候只添加了两个beanpostprocessor,
// 我们自定义的beanpostprocessor并不会被加进去,至于用户自定义的beanpostprocessor
// 什么时候调用后面会有详细的分析,很重要 !
// 最后是添加一些spring本身需要用到的工具bean
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
// 点进去查看这个方法是空的,不过从名字和注释上我们可以看的出这一个方法主要是
// 提供给实现了该抽象类的一个扩展beanFactory的机会,跳过
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
// 要理解这个方法需要知道BeanFactoryPostProcessor:如果说一个bean实现了BeanFactoryPostProcessor
// 那么容器初始化之后会执行bean内部的postProcessBeanFactory方法(注意并不是BeanPostProcessor),
// 这是在容器的层面上给我们的bean提供的一种扩展机制(平时并不是太常用到)。
// 由于在obtainFreshBeanFactory这一步我们就已经获取到beanFactory这个对象了,
// 因此bean的信息(这里说的信息是指beanDefinition)其实已经加载进去了
// 也就意味着我们知道那些bean实现了BeanFactoryPostProcessor这个接口了,因此接下来
// 就是调用实现了beanfactoryPostProcessor这个接口的bean的postProcessBeanFactory方法了
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// 注册beanPostProcessor的实现类到容器中(前面我们已经说过了,在obtainFreshBeanFactory调用完之后
// 我们就已经知道了所有的beanDefinition,自然也就知道了所有的bean是不是实现了BeanPostProcessor)
// ,注意并不是beanFactoryPostProcessor!BeanPostProcessor是在Bean的层面上提供的一种扩展机制
// 里面包含了两个重要的方法:postprocessBeforeInitialization和postprocessAfterInitialization,
// 这两个方法分别会在bean实例化之前和实例化之后执行
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
// 这一步是和国际化相关的,不重要
initMessageSource();

// Initialize event multicaster for this context.
// 初始化ApplicationContext事件广播器
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// 这个方法也是空的,注释如上也说明的很详细了,是提供给子类实现的接口目的是
// 在实例化正常的bean之前实例化一些特殊的bean,这里也体现了
// spring处处可扩展的一种机制(虽然看起来并没有什么卵用)
onRefresh();

// Check for listener beans and register them.
// 注册事件监听器,应该是和事件广播器有一定的关系,监听器需要实现ApplicationListener接口
registerListeners();

/**
*
*
* 到这一步就是分水岭,接下来就会初始化正常的java bean了
*
* **/
// Instantiate all remaining (non-lazy-init) singletons.
// 重点强调一下,在这之前并不会生成bean对象,这一步是会将所有的非lazy-init的对象都给实例化。
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
// 最后广播事件,告知容器已经完成初始化的操作
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

看起来也不是太复杂嘛,嗯,也就是乍一看。上面我们有说过容器创建的目的:持有资源,接下来的 分析请牢记这句话,不然看着看着保证能让你跪掉。

按照上面的代码,我们先来看一下obtainFreshBeanFactory这个方法吧, 毕竟这个方法执行完毕之后我们就会得到一个beanFactory,当然也就是 我们的容器。代码如下:

1
2
3
4
5
6
7
8
9
10
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 关闭旧的容器,并创建新的容器,加载bean的定义,这一步并不会实例化bean(已经不是第一次强调了:本节只关心容器的初始化)
refreshBeanFactory();
// 返回持有的容器(beanFactory)
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

如上核心代码自然就是refreshBeanFactory了,我们点进去看一下refresBeanFactory都做了那些操作吧, 不过很遗憾方法是抽象的,那肯定是在子类里面有实现吧。没错方法是在AbstractRefreshableApplicationContext,上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected final void refreshBeanFactory() throws BeansException {
// 判断是否已经存在beanFactory了,如果已经存在了则需要销毁所有的bean并关闭beanFactory(这也解释了上面的方法为什么叫做refresh,而不是init)
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 初始化一个beanFactory,这一步其实就是返回一个
// DefaultListableBeanFactory至于为什么是defaultlistablebeanfactory是
// 因为实现的接口多,方便用户操作呗
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 设置beanFactory的两个属性:beandefinition允许覆盖和允许循环引用
customizeBeanFactory(beanFactory);
// 加载beandefinition到beanfactory中
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

上面注释也是比较详细了,核心代码的话就是loadBeanDefinitions:将bean的定义转换成BeanDefinition加载到beanFactory中 ,最终的格式就是<beanName, beanDefinition>,继续跟进代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
// 实例化一个beanDefinitionReader,该对象持有一个beanFactory实例,在解析完之后会讲解析数据写入beanFactory
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
// 可以定制初始化reader,略过
initBeanDefinitionReader(beanDefinitionReader);
// 核心代码
loadBeanDefinitions(beanDefinitionReader);
}

顺接上文,我们进去loadBeanDefinitions方法查看一下:

1
2
3
4
5
6
7
8
9
10
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}

这里在强调一下,我们的reader内部已经持有beanFactory对象,我们接下来只需要继续跟进loadBeanDefinitions方法即可:

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
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
Resource[] var3 = resources;
int var4 = resources.length;
// 遍历加载给定的文件,这里就是我们指定的application-context.xml文件
for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
// 往下跟
counter += this.loadBeanDefinitions((Resource)resource);
}

return counter;
}

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 继续往下跟
return this.loadBeanDefinitions(new EncodedResource(resource));
}


public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isInfoEnabled()) {
this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}

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 {
// 将给定的文件转换成一棵DOM树,方便操作
Document doc = this.doLoadDocument(inputSource, resource);
// 解析dom文件并注册到registry,前面我们就已经说过
// reader在实例化的时候会持有一个BeanFactory,
// 而这个beanfactory恰恰就是registry(构造函数有类型强转),通过this.getRegistry()获取到的就是beanfactory
return this.registerBeanDefinitions(doc, resource);
} catch (BeanDefinitionStoreException var4) {
throw var4;
} catch (SAXParseException var5) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var5.getLineNumber() + " in XML document from " + resource + " is invalid", var5);
} catch (SAXException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var6);
} catch (ParserConfigurationException var7) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var7);
} catch (IOException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var8);
} catch (Throwable var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var9);
}
}

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;
}

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
// 获取对应xml文件的根节点
Element root = doc.getDocumentElement();
// 从根节点开始解析并注册beandefinition
this.doRegisterBeanDefinitions(root);
}

// 从指定的节点解析并注册beanDefinition
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.

// 负责解析beans的代理类
BeanDefinitionParserDelegate parent = this.delegate;
// 由于beans标签下面也会有beans标签,因此这里的代理类也会随着beans的内嵌而内嵌,表现出来就是用parent来构造delegate
this.delegate = createDelegate(getReaderContext(), root, parent);

if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
// 预留给子类扩展,来额外的处理xml
preProcessXml(root);
// 解析beandefinition并注册,核心代码
parseBeanDefinitions(root, this.delegate);
// 预留给子类扩展,来额外的处理xml
postProcessXml(root);

this.delegate = parent;
}

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)) {
// 解析default namespace下的元素
parseDefaultElement(ele, delegate);
}
else {
// 解析自定义的namespace下的元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}

上面代码中我们看到,代码最终的执行分成两块:parseDefaultElement、parseCustomElement, 如果解析的节点是beans、bean、import、alias 走的就是parseDefaultElement方法,至于其他的标签, 后文我们会通过spring的扩展机制来具体展示一些这种机制(主要是namespace、xsd、以及namespacehandler)。 由于我们本节主要是探讨IOC的机制,因此我们关心的标签其实是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
// 以下方法有些跳跃,因为不重要的代码是在太多,到这里其实已经不是太重要了,因为这里涉及到的仅仅是DOM树的解析
// 这里我们看到readerContext可以猜想到该context保存的是当前这个reader的公共的资源
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 核心!解析bean对象
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
// 解析配置文件,将配置文件中的信息提取出来,写入beandefinition
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}

String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}

if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 核心代码,一旦该方法执行完成之后,就已经生成了对应的beandefinition对象
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
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);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}

return null;
}

上面这一步结束之后,我们就已经获取到了beandefinitionHolder对象了,不过请注意,这里有两个循环, 第一个是遍历资源路径加载资源,本例中就是我们的application-context.xml文件,另外一个循环是在某一个 文件加载之后解析标签的过程中循环遍历的。

在完成beandefinitionholder初始化之后,我们就可以注册该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
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 ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}

BeanDefinition oldBeanDefinition;

oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}

if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}

整体看下来,主要的流程也就是向beandefinitionmap中添加对应的beanName和beanDefinition,暂时可以先告一段落。到此 我们已经分析了容器的初始化的流程及中间的操作。总结起来如下步骤:

  • 创建容器
  • 加载文件并创建dom解析器
  • 根据标签的namespace选择不同的解析流程
  • 将解析之后的beandefinition注册到容器中

bean的实例化

在上文中我们将spring的初始化分为两个部分,本小结我们就来看一下bean的实例化是一个什么样的过程,方法入口为 finishBeanFactoryInitialization(其实在这之前我们实现了beanfactorypostprocessor接口的类的postprocessbeanfactory 不是已经调用过了么?既然方法都已经调用过了,那对应的对象是不是在这之前也已经生成了呢?是的, 在invokeBeanFactoryPostProcessors方法的时候就已经生成了对应的对象了,实例化的方法也和正常的实例化没什么区别), 这一步是会将所有的非lazy-init的singleton都给实例化,所谓的lazy-init是在使用到的时候才回去实例化的一种机制, 注意上面容器初始化是将xml文件映射为beandefinition,而此处的初始化则是生成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
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// conversion_service_bean工程上用到的不是太多,略过
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 获取切面相关的java bean,略过
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
// 初始化所有的非lazy-init的单例
beanFactory.preInstantiateSingletons();
}

// 接上文实例化非lazy-init的单例
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
// 初始化所有单例对象
for (String beanName : beanNames) {

// 这一步涉及到bean的继承,可以暂时略过
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 满足初始化的条件:非抽象、单例、非lazy-init
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 针对factorybean特有的处理方法,判断其是否迫切需要初始化,如果是则立即获取对应的bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
// 核心方法
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
// 到这里应完成所有对象的初始化,接下来会对SmartInitializingSingleton这种类型的bean执行回调函数
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

//如上我们继续跟进getBean这一块代码:
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {

// 这一步是针对factorybean所做的特殊处理
final String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
// 这一步检测早期引用是否已经创建该单例(其实是是否存在循环引用导致bean的创建),
// 首先会从singleObject中获取对应的bean,如果获取不到
// 接着会从earlySingletonObjects中获取对应的bean,最后会从singletonFactories获取
// 创建bean的factorybean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
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的话,返回的是sharedInstance,如果是factorybean的话反回的是getObject方法返回的对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// protype类型的javabean不允许循环引用
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}

if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

/**
* 正常情况下,创建java bean都是会走到这一步
* **/
try {
// 获取beanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
// 获取当前bean依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册依赖关系
registerDependentBean(dep, beanName);
try {
// 首先初始化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// 正常的创建bean的流程,上面已经完成了当前bean所依赖的bean的创建了,接下来就是创建当前的bean了
// 由于是初始化,条件限制很明显了,只会走到第一步创建javabean
// Create bean instance.
if (mbd.isSingleton()) {
// 创建单例
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
// 如果sharedInstance是factorybean,返回getObject方法返回的对象,否则返回sharedInstance
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {
// 创建prototype实例
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
// 其他作用域的bean实例:request等
String scopeName = mbd.getScope();
final 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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, 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 " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}

// 上面创建java bean都有用到的方法就是createBean,我们继续跟进一下

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 加载beandefinition中指定的class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
// 准备bean中要求重写的方法,是提供给bean的一种扩展机制
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// TODO 让InstantiationAwareBeanPostProcessor有机会返回代理,
// 这一步也很重要,注意并不是要求bean实现BeanPostProcessor!
// 如果是切面的话,到此就截止了
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

// 核心方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}


// 我们继续上面的核心方法跟进:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建bean实例,到了这一步我们就完成了bean实例的创建
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充bean
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 回调函数,好像是包括InitializingBean、beanpostprocessor,这里用到的beanpostprocessor和前面
// 可能会产生的增强是一致的,同样都是获取beanpostprocessor,只不过前面存在类型的判断
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!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.");
}
}
}
}

// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}

接下来会分别看一下容器实例化的三个步骤:

创建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
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);

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());
}
// 采用工厂方法实例化对象,这里我们看到factorymethod是beandefinition的一个属性,没错,
// factorymethod在bean的标签上确实是作为一个属性而存在
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// Shortcut when re-creating the same bean...
// 这一部分可以暂时跳过,其涉及到的是prototype类型的java bean的创建过之后再次创建的短路操作(快速决定构造函数)
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}

// Need to determine the constructor...
// 对于没有进入短路操作的java bean的构建,此处就是获取其构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数依赖注入
return autowireConstructor(beanName, mbd, ctors, args);
}

// No special handling: simply use no-arg constructor.
// 无参构造函数
return instantiateBean(beanName, mbd);
}

// 简单起见我们就挑一个无参构造函数来看

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
// 核心方法
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

// 继续跟进核心方法我们会看到
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
// 如果不存在方法覆写就进入到这个分支,方法覆写相关的属性分别是lookup-method、replace-method
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 使用指定的构造函数初始化java bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 对于存在方法覆写的bean是通过cglib字节码增强的方式生成的,
// 注意这里和切面并没有什么关系,切面在进入初始化之前就已经短路出去了
// 这里只不过是使用cglib做的字节码增强(虽然切面也是使用cglib做的字节码增强)
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

到此为止,我们所需要的bean已经完成创建,只不过这个bean还空空如也,还需要填充相关的属性,当然最重要的是我们在代码里面使用 Autowired的方式装配的一些属性了。

属性填充

填充属性代码如下:

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
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();

// 正常的流程来说这里我们获取到的bw肯定不是null,bw就是我们上一步生成的bean的持有者
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// InstantiationAwareBeanPostProcessors类提供了在bean的实例化完成后、属性填充前的扩展机制
// 这也是一种BeanPostProcessor,只不过比较特殊,后面回调函数还会分析BeanPostProcessor
boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 设置bean属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}

回调函数

代码如下:

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
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// Aware接口回调
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// beanPostProcessor的postprocessBeforeinitialization方法回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// init方法回调
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// beanpostprocessor的postprocessafterinitialization方法回调
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

代码分析到此可以截止一个段落了,或许对我们来说依然是非常凌乱了,那我们还是总结一下上面创建javabean的思路吧: 在容器的初始化阶段我们获取的信息是beandefinitionMap,存放beanname和beandefinition的一个map, 有了这个信息我们就知道了我们要创建哪些bean了,接下来只要遍历这个map的key创建对应的bean就可以了,首先会根据是否是 factorybean及eargeinit来决定是否需要马上创建,总之如果需要创建的话,最终都会走到同一个地方, 接下来会判断是否由于循环引用导致创建该单例的对象提前创建了,如果对象提前创建了那直接返回就完事了,如果没有创建就会走到 正常的创建流程,在正常创建之前还可以通过instinationawarebeanpostprocessor的切面操作来短路掉创建对象的过程, 最后正常的创建流程也比较简单,就是反射生成对象、填充属性、执行回调函数,这里回调函数的顺序是aware、postprocessorbeforeinitinalition 、init-method、postprocessorafterinitinalition(执行的是当前这个bean的回调函数!!)

总结

关于IOC的总结到此为止,后面会整理个小例子演示一下spring的扩展机制