Spring源码学习笔记之IOC

前言

Spring源码学习笔记,Spring-Ioc源码浅析,错误之处欢迎指正,共同学习

介绍

Ioc 容器的核心是控制对象的创建,销毁,管理对象之间的依赖关系,并由IOC容器完成对象的注入。我们只需要关注业务逻辑。

IOC 原理

Ioc 底层通过 java 反射创建实例,利用set方法对实例的依赖进行注入。

搭建源码研究环境

  1. 直接从 spirng 的 github 上 clone spring-framework 源码,部署项目

  1. debug 启动该项目,运行main方法
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {

ApplicationContext ctx = new FileSystemXmlApplicationContext(
"spring-context/src/test/resources/org/springframework/context/lishqTest/beans.xml");
System.out.println("begin...");
System.out.println("number : " + ctx.getBeanDefinitionCount());
System.out.println(((TestBean) ctx.getBean("beans1.bean1")).getName());
System.out.println(((TestBean) ctx.getBean("beans1.bean2")).getObjRef());
}

输出

new Instance......when
new Instance......when
begin...
number : 2
lishq-toSpring
test.lishqTest.TestBean@329302

Spring的IOC实现

  1. 资源(Resource)定位.
  2. BeanDefinition 的载入和 BeanFactory 的构造.
  3. 向 IOC 容器(BeanFactory)注册 BeanDefinition.
  4. 根据 lazy-init 属性初始化 Bean 实例和依赖注入.

IOC中几个重要概念及其关系

1.BeanFactory
2.ApplicationContext
3.BeanDefinition
--------------------------------------------------------------------
1.BeanFactory是IOC容器的接口定义,定义了容器的基本功能
    a.获取Bean
    b.注册Bean
    c.more

2.ApplicationContext 则是扩展后的容器,它通过继承 MessageSource,ResourceLoader,ApplicationEventPublisher 接口,在BeanFactory 简单IOC容器的基础上添加了许多对高级容器的支持。
    a.MessageSource 接口,提供了消息处理的功能。在web项目上用于国际化
    b.ResourceLoader 是资源加载接口,用于对不同的Resource进行加载。Resource getResource(String location)通过一个标识加载资源信息。
    c.ApplicationEventPublisher 提供了发布 event 组件的接口。spring 的事件体系 和Spring内置事件处理

3.BeanDefinition 可简单理解为容器实现依赖反转功能的核心数据结构
    a.Spring 通过定义 BeanDefinition 来管理基于Spring 的应用中的各种对象以及他们直接的相互依赖关系
    b.BeanDefinition 抽象了我们对 Bean的定义,是让容器起作用的主要数据类型

Spring Bean 解析过程

Spring Bean 解析过程如上图所示,下面我们据此逻辑debug源码

FileSystemXmlApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// FileSystemXmlApplicationContext 的构造方法,默认刷新为true
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}

// 该构造器做了2件事情,一是设置配置文件,二是刷新容器。
public FileSystemXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {

super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();// 初始化容器核心方法
}
}

AbstractApplicationContext.refresh()

  • 构建BeanFactory,以便于产生所需的 Bean
  • 注册可能感兴趣的事件
  • 创建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
// 整个IOC容器初始化的所有逻辑
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 为刷新准备应用上下文
prepareRefresh();

// 告诉子类刷新内部bean工厂,即在子类中启动refreshBeanFactory()的地方----创建bean工厂,根据配置文件生成bean定义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 准备在此上下文中使用的bean工厂。
prepareBeanFactory(beanFactory);

try {
// 允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);

// 调用在上下文中注册为bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);

// 注册拦截bean创建的bean处理器。
registerBeanPostProcessors(beanFactory);

// 初始化此上下文的消息源。
initMessageSource();

// 初始化上下文中的事件机制
initApplicationEventMulticaster();

// 初始化特定上下文子类中的其他特殊bean。
onRefresh();

// 检查监听Bean并且将这些Bean向容器注册
registerListeners();

// 实例化所有的非延迟加载的单例类
finishBeanFactoryInitialization(beanFactory);

// 发布容器事件,结束refresh过程
finishRefresh();
}

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

// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
destroyBeans();

// 重置“active”标志
cancelRefresh(ex);

// 将异常传播给调用方。
throw ex;
}

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

Spring 通过 refresh 操作重建了 ApplicaitonContext,在这个过程中同时也构建了默认的 BeanFactory 以及加载了 BeanDefinition。AbstractApplicationContext类在refresh()方法中调用了obtainFreshBeanFactory, 此方法主要负责重建BeanFactory以及加载BeanDefinition。 下面我们对此方法进行简要分析:

obtainFreshBeanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
// 如果存在就销毁
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 设置序列化
beanFactory.setSerializationId(getId());
// 定制的BeanFactory
customizeBeanFactory(beanFactory);
// 使用BeanFactory加载bean定义 AbstractXmlApplicationContext
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

可以看到BeanFactory的创建过程,首先判断是否已存在BeanFactory,如果已存在则销毁:
destroyBeans() 清除Bean引用的缓存
closeBeanFactory() 释放已创建的BeanFactory

其次调用 createBeanFactory 建立默认的 BeanFactoryDefaultListableBeanFactory,也就是 BeanFactory的默认实现;

当BeanFactory建立好之后,进行一项简单的配置 customizeBeanFactory(),以决定在加载 BeanDefinition 的过程中是否允许循环引用以及是否允许对已有BeanDefinition进行覆写。

然后我们看到一个很感兴趣的方法,就是 loadBeanDefinitions(beanFactory),看名字是加载 Definitions,Definition 是核心之一,代表着 IOC 中的基本数据结构。该方法也是个抽象方法,默认实现是 AbstractXmlApplicationContext ,我们看看该方法实现:

loadBeanDefinitions

  1. XmlBeanDefinitionReader loadBeanDefinitions();
  2. doLoadBeanDefinitions();
  3. registerBeanDefinitions();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 首先创建一个 XmlBeanDefinitionReader ,用于读取XML中配置,设置了环境,资源加载器,
* 最后初始化,加载。可以说,该方法将加载,解析Bean的定义,也就是把用户定义的数据结构
* 转化为 IOC容器中的特定数据结构。
*/
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为给定的BeanFactory创建一个新的XmlBeanDefinitionReader
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));

// 允许子类提供自定义的读取器初始化,然后继续实际加载bean定义
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}

我们主要关注该方法的 loadBeanDefinitions(beanDefinitionReader) 就是BeanDefinition的主要加载过程。它使用指定的 XmlBeanDefinitionReader 进行加载BeanDefinition。这个方法仅负责加载或者注册BeanDefinition,而生命周期是通过bean工厂的refreshBeanFactory方法管理

loadBeanDefinitions

1
2
3
4
5
6
7
8
9
10
11
12
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 获取是否有配置好的Resource,如果有直接交由reader进行加载
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 加载给定的路径文件
reader.loadBeanDefinitions(configLocations);
}
}

可以看出,对于BeanDefinition的加载最终是使用 XmlBeanDefinitionReader 的实例进行加载的,此处只是对其指定了加载的资源或者资源的位置。

1
2
3
4
5
6
7
8
9
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
// 循环加载配置文件
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}

此方法位于AbstractBeanDefinitionReader类中,主要针对字符串路径进行解析,最终得到Resource对象,然后将Resource交由XmlBeanDefinitionReader进行处理。所以针对 xml 的资源加载的最终位置还是位于XmlBeanDefinitionReader中

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
// 从指定的资源位置加载bean定义,返回找到的bean定义的数量
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
// 获取资源加载器
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}

if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
// 循环加载resource 资源数组
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
// 根据配置文件加载Bean定义
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
// ......
return count;
}
}
else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
return count;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 根据输入流加载 Document 文档对象,然后根据得到的文档对象注册到容器
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {

try {
Document doc = doLoadDocument(inputSource, resource);
// 真正的注册bean
int count = registerBeanDefinitions(doc, resource);
// ......
return count;
}
// ......
}

可以看到通过 doLoadDocument 方法将其解析为Document对象,然后通过 registerBeanDefinitions 方法对 Document 对象进行提取与 BeanDefinition 的注册.

这里的Document是符合 w3c 定义的标准xml文档; 我们知道xml解析一般有DOM方式(document)、SAX方式(Simple API for XML)以及StAX(Streaming API for xml)方式;
而此处的Resource不会包含太大量的信息,所以采用了DOM方式,即一次将整个XML都加载到内存中进行解析.

registerBeanDefinitions

  1. DefaultBeanDefinitionDocumentReader
  2. registerBeanDefinitions();
  3. doRegisterBeanDefinitions();
  4. parseBeanDefinitions();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 解析文档中根层次的元素:“import”、“alias”、“bean”
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)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}

解析root的过程,判断root为spring默认标签还是用户自定义标签,分别交由不同委托类解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// 通过resource属性取得配置文件的位置,然后将其转换为Resource,交由XmlBeanDefinitionReader来解析
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
// 进行是否可重写校验和循环引用校验后,将alias标签的name和alias属性添加到上下文的aliasMap中;
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// 处理和注册bean
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// beans标签,进行迭代调用doRegisterBeanDefinitions方法
doRegisterBeanDefinitions(ele);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
* 处理给定的 bean 元素,解析 bean 定义,并在注册中心注册。
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 创建一个 BeanDefinitionHolder
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);
}
// 执行容器通知事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}

首先创建一个 BeanDefinitionHolder,该方法会调用 BeanDefinitionReaderUtils.registerBeanDefinition 方法, 最后执行容器通知事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 向给定的bean工厂注册给定的bean定义
* @param definitionHolder bean定义,包括名称和别名
* @param registry 要注册的bean工厂
* @throws BeanDefinitionStoreException 如果注册失败,抛出BeanDefinitionStoreException
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {

// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
// 将bean的名字和 BeanDefinition 注册
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}

首先从bean的持有者那里获取了beanName,然后调用 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()), 将bena的名字和 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
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 existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// ......
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<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// 仍处于启动注册阶段,最终放进这个map 实现注册
// private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}

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

注册bean的最后一步,将beanName和 beanDefinition 放进一个 ConcurrentHashMap(256) 中。

那么这个 beanDefinition 是时候创建的呢? 就是在 DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 方法中,在这里创建了 BeanDefinitionHolder, 而该实例中解析Bean并将Bean 保存在该对象中。所以称为持有者。
该实例会调用 parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) 方法,该方法用于解析XML文件并创建一个 BeanDefinitionHolder 返回,该方法会调用 parseBeanDefinitionElement(ele, beanName, containingBean) 方法:

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
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {

// 入栈,用于跟踪解析过程
this.parseState.push(new BeanEntry(beanName));

String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
// public static final String CLASS_ATTRIBUTE = "class";
// 从XML元素中取出 class 元素
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}

try {
// 根据class属性和parent属性创建BeanDefinition,
// 首先通过类加载器寻找class类并将其设置于beanClass属性
// 如果类加载器暂时无法发现此类,则将class设置于beanClassName属性上
AbstractBeanDefinition bd = createBeanDefinition(className, parent);

parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);

bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));

return bd;
}
// ......
finally {
this.parseState.pop();
}

return null;
}

我们看看该方法,可以看到,该方法从XML元素中取出 class 元素,然后拿着 className 调用 createBeanDefinition(className, parent) 方法,该方法核心是调用 BeanDefinitionReaderUtils.createBeanDefinition 方法:

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 AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {

return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}

public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {

// 泛型的bean定义,也就是最终生成的bean定义。
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
// 设置Class 对象,该对象就是我们在配置文件中配置的Class对象。最后返回。
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}

该方法很简单,创建一个 Definition 的持有者,然后设置该持有者的Class对象,该对象就是我们在配置文件中配置的Class对象。最后返回。

至此,xml中定义的BeanDefinition元数据被注册至应用上下文中,创建bean工厂,生成Bean定义。但还没有实例化该类。

Spring ioc 依赖注入及lazy-init

我们刚刚创建了Bean工厂,并创建 BeanDefinitions 放进 Map 里,以beanName为key。那么我们现在有了Bean定义,但还没有实例,也没有构建Bean与Bean之间的依赖关系。 接下来我们看如何实例及构建 Bean 依赖关系

1:BeanDefinition 保存所有 bean 定义及依赖关系
2:解析所有 bean 定义,存储到 BeanDefinition 中
3:getBean() 时,触发 ioc 依赖注入
4:getBean() 由使用或者 context 中的 finishBeanFactoryInitialization() 循环触发(判断是否lazy,是否是单例)
5:创建bean自身---由 factoryBean 或者自定义的 facotry-method 或者默认构造方法(cglib或class.newInstance())

6:ioc 依赖注入:
    A: - BeanDefinitionValueResolver,判断各种属性类型获取属性值(如果ref引用类型,递归调用getBean(),其它则返回对应值)
    B: - 正式注入:BeanWrapper.setPropertyValues()

AbstractApplicationContext.refresh().finishBeanFactoryInitialization(beanFactory) 实例化所有的非延迟加载的单例类

preInstantiateSingletons

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
public void preInstantiateSingletons() throws BeansException {
// private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// 触发所有非延迟单例bean的初始化...
// 创建bean并递归构建依赖关系
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 创建bean
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}

// 为所有适用的bean触发初始化后回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

doGetBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name);
Object bean;

// ......
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
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 {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

// ......
}
}

// ......
return (T) bean;
}

可以看到,该方法首先会获取依赖关系,拿着依赖的BeanName 递归调用 getBean方法,直到调用 getSingleton 方法返回依赖bean,而 getSingleton 方法的参数是 createBean 返回的实例,该方法内部调用 AbstractAutowireCapableBeanFactory.doCreateBean 方法:

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
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
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.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充Bean,发生依赖注入的地方
populateBean(beanName, mbd, instanceWrapper);
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<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(......);
}
}
}
}

// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
// ......

return exposedObject;
}

核心代码:

  1. instanceWrapper = createBeanInstance(beanName, mbd, args) 创建实例。
  2. populateBean(beanName, mbd, instanceWrapper) , 用于填充Bean,发生依赖注入。

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
49
50
51
52
53
54
55
56
57
58
/**
* 使用适当的实例化策略,为指定的bean创建一个新实例:
* 工厂方法、构造函数自动连接或简单实例化.
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保bean类在这一点上得到了实际的解析.
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());
}

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}

if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// Shortcut when re-creating the same 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);
}
}

// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}

// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}

// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

该方法首先创建Class 对象,然后获取构造器对象,最后调用 instantiateBean(beanName, mbd)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 使用它的默认构造函数实例化给定的bean.
*/
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
// ......
}

该方法核心逻辑是 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent),携带BeanName,RootBeanDefinition ,发挥的策略对象是 SimpleInstantiationStrategy,该方法内部调用静态方法 BeanUtils.instantiateClass(constructorToUse), 最后调用 Constructor 的 newInstance 方法,
也就是最终使用反射创建了该实例:

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

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
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(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 判断是否是 Kotlin 类型。如果不是,则调用构造器的实例方法
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
// ......
}

到这里,我们的实例已经创建。但是我们的实例的依赖还没有设置:

  • populateBean(beanName, mbd, instanceWrapper) , 用于填充Bean,依赖注入。

populateBean

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
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 {
// 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.
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;
}

// 获取该bean的所有属性,也就是我们配置property元素
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

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

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}

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

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}

if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}

MutablePropertyValues mpvs = null;
List<PropertyValue> original;

if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}

TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

// 创建一个深度副本,解析值的任何引用
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// 获取 pvName 所对应的容器value
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}

// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
// ......
}

该方法核心逻辑是 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null), 即获取该 bean 的所有属性,也就是我们配置的 property 元素。最后执行 applyPropertyValues(beanName, mbd, bw, pvs) 方法。现在的PropertyValues 都是字符串,没有值,这个方法的作用就是获取值,关键代码:Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue),该方法会获取 pvName 所对应的容器 value,该方法内部会调用 BeanWrapperImpl.resolveReference(argName, ref) 方法

resolveReference

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
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
// 根据属性名从容器中获取实例,递归
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}

public void setValue(final @Nullable Object value) throws Exception {
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
}
}

该方法是最后一步,我们看到该方法会找到set方法,然后调用 Method 的 invoke 方法,完成属性注入。

总结

Spring 的 Bean 其实就是 BeanDefinition,在 Bean 的创建和依赖注入的过程中,需要根据 BeanDefinition 的信息来递归的完成依赖注入。这些递归都是以 getBean() 为入口的,一个递归是在上下文体系中查找需要的 Bean 和创建 Bean 的递归调用;另一个 Bean 是在依赖注入时,通过递归调用容器的 getBean 方法,得到当前的依赖 Bean,同时也触发对依赖 Bean 的创建和注入。在对 Bean 的属性进行依赖注入时,解析的过程也是一个递归的过程,这样,根据依赖关系,一层一层的完成 Bean 的创建和注入,直到最后完成当前 Bean 的创建。有了这个顶层 Bean 的创建和对他的属性依赖注入的完成,意味着当前 Bean 相关的整个依赖链的注入也完成了。

------本文结束感谢阅读------
显示评论
0%