Spring源码阅读(一)

1 前言

​ 阅读源码可以帮助提高debug能力以及更加熟悉该框架的原理与构建方式,学习大师的思维。本系列文章将会通过阅读Spring源码,尽力分析各个函数,类,接口等的实现方式与原理,来让自己更加深刻理解这一框架。

​ 首先,我们要知道,Spring是一个生态体系,其中包含了Spring Framework, Spring Boot, Spring Cloud等,一般说的Spring源码是指Spring Framework中的。

​ 而在Spring Framework中,又会有许多模块所组成

Spring架构图

一共有以下20多个不同的模块

1
2
3
4
5
spring-aop      spring-context-indexer  spring-instrument  spring-orm    spring-web
spring-aspects spring-context-support spring-jcl spring-oxm spring-webflux
spring-beans spring-core spring-jdbc spring-r2dbc spring-webmvc
spring-context spring-expression spring-jms spring-test spring-websocket
spring-messaging spring-tx

​ 而我们知道,Spring最核心的功能就是IOC和AOP,也是本次源码分析的重点

​ 在图中,也就是Core Container中的模块和AOP、Aspects。接下来,说说大致作用:

  • Beans 模块:提供了框架的基础部分,包括控制反转和依赖注入。
  • Core 核心模块:封装了 Spring 框架的底层部分,包括资源访问、类型转换及一些常用工具类。
  • Context 上下文模块:建立在 Core 和 Beans 模块的基础之上,集成 Beans 模块功能并添加资源绑定、数据验证、国际化、Java EE 支持、容器生命周期、事件传播等。ApplicationContext 接口是上下文模块的焦点。
  • AOP 模块:提供了面向切面编程实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中,这样各司其职,降低业务逻辑和通用功能的耦合。
  • Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。

大致了解了以后,将进入源码分析了

2 环境搭建

新建一个maven项目以后,导入以下pom文件

pom.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>spring_core</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.15</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.15</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.15</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.15</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.15</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

</dependencies>

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

</project>

applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
<?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="person" class="com.w1nd.spring.dao.Person">
<property name="age" value="23"/>
<property name="name" value="Bruis"/>
</bean>

</beans>

Person.java

1
2
3
4
5
6
7
8
9
package com.w1nd.spring.dao;

import lombok.Data;

@Data
public class Person {
private Integer age;
private String name;
}

3 IoC过程

​ IoC(控制反转)简单来说就是将创建Bean和注入Bean的权利赋予给了Spring容器,不用程序员自己去管理,在bean生成或初始化的时候,Spring容器就会将数据注入到bean中,又或者通过将对象的引用注入到对象数据域中的方式来注入对方法调用的依赖。

​ 在Spring容器的设计中,有两个主要的容器机制:

  • 实现BeanFactory接口的简单容器系列

    ​ 实现了容器最基本的功能

  • ApplicationContext应用上下文

    ​ 除了拥有BeanFactory的所有功能外,还支持特殊类型bean如上一节中的BeanFactoryPostProcessor和BeanPostProcessor的自动识别、资源加载、容器事件和监听器、国际化支持、单例bean自动初始化等。

对于这两个容器,DefaultListableBeanFactory是是Spring注册及加载bean的默认实现,我们可以直接使用该类来加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.w1nd.spring;

import com.w1nd.spring.dao.Person;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringMain {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("applicationContext.xml");

Person person1 = (Person) beanFactory.getBean("person");
System.out.println(person1);
}
}

但在下面演示中,为了更好的了解spring一系列衍生方案,使用ClassPathXmlApplicationContext来加载xml文件,演示程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.w1nd.spring;

import com.w1nd.spring.dao.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringMain {
public static void main(String[] args) {
//使用spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person)context.getBean("person");
System.out.println(person);
}
}

​ 另外,我们来看DefaultListableBeanFactory和ClassPathXmlApplicationContext两个类的继承链图,这对于接下来的debug会更有帮助

image-20220208155138114

image-20220208155337861

​ 建议将该图画下来,debug时对着用箭头标明,这样不会混乱

​ 下面对上述演示程序debug

3.1 初始

  1. 加载ContextClosedEvent,以免后续出现问题

  2. ClassPathXmlApplicationContext构造函数(ClassPathXmlApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
    }

    /*
    使用给定的父类容器创建新的ClassPathXmlApplicationContext,然后从给定的XML文件加载定义,
    加载所有bean定义并且创建所有的单例,在进一步配置上下文后调用refresh。换句话说xml文件的读取,
    bean的创建和实例化都是在refresh()方法中进行的,refresh()函数中包含了几乎所有的
    ApplicationContext中提供的全部功能。
    */
    public ClassPathXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

    super(parent);
    //设置配置路径
    setConfigLocations(configLocations);
    if (refresh) {
    //refresh Spring容器 很重要,这个方法
    refresh();
    }
    }
  3. 设置配置路径(AbstractRefreshableConfigApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //给configLocations字符串数组设置值,支持多个配置文件已数组方式同时传入。
    public void setConfigLocations(@Nullable String... locations) {
    if (locations != null) {
    Assert.noNullElements(locations, "Config locations must not be null");
    this.configLocations = new String[locations.length];
    for (int i = 0; i < locations.length; i++) {
    this.configLocations[i] = resolvePath(locations[i]).trim();
    }
    }
    else {
    this.configLocations = null;
    }
    }

3.2 refresh

  1. refresh函数(AbstractApplicationContext.class

    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
    /*
    简单来说,Spring容器的初始化是在refresh()方法来启动的,这个方法标志着IOC容器的正式启动。
    具体来说,这里的启动包括了BeanDefinition和Resource的定位、载入和注册三个基本过程。
    */
    @Override
    public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

    // 准备刷新容器(上下文环境)
    prepareRefresh();

    // 通知子类刷新内部bean工厂,初始化BeanFactory并进行XML的解析读取
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

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

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

    StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
    // 调用在上下文中注册为 bean 的工厂处理器。
    invokeBeanFactoryPostProcessors(beanFactory);

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

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

    // 为此上下文初始化事件多播器。
    initApplicationEventMulticaster();

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

    // 检查侦听器 bean 并注册它们。
    registerListeners();

    // 实例化所有剩余的(非惰性初始化)单例。
    finishBeanFactoryInitialization(beanFactory);

    // 最后一步:发布相应的事件。
    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();
    contextRefresh.end();
    }
    }
    }

    ​ 鉴于该方法的重要性,下面对其函数名分目录分别讲解,每个函数会逐渐深入其子函数去分序号,部分不会讲的可能不太重要或仅知道该函数作用即可。往后,每个函数名后面会写明所在类,部分辅助函数和其他函数放在同个代码块说明,代码块的函数通常在同个类,如果不在,会在注释标明

3.3 prepareRefresh

  1. prepareRefresh()(AbstractApplicationContext.class

    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
    /*
    准备此上下文以进行刷新、设置其启动日期和活动标志以及执行任何属性源的初始化。
    */
    protected void prepareRefresh() {
    // 切换到活动状态
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
    if (logger.isTraceEnabled()) {
    logger.trace("Refreshing " + this);
    }
    else {
    logger.debug("Refreshing " + getDisplayName());
    }
    }

    // 初始化上下文环境中的任何占位符属性源。这里对于子类啥都不会干
    initPropertySources();

    // 验证所有标记为必需的属性都是可解析的:
    // 请参阅 ConfigurablePropertyResolvesetRequiredProperties
    getEnvironment().validateRequiredProperties();

    // 存储预刷新 ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
    this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
    // 将本地应用程序侦听器重置为预刷新状态。
    this.applicationListeners.clear();
    this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 允许收集早期应用程序事件,一旦多播器可用就发布...
    this.earlyApplicationEvents = new LinkedHashSet<>();
    }

3.4 obtainFreshBeanFactory

该方法的时序图

image-20220210135522201

  1. obtainFreshBeanFactory (AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    /*
    告诉子类刷新内部 bean 工厂。会返回新的BeanFactory实例
    */
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
    }
  2. refreshBeanFactory(AbstractRefreshableApplicationContext.class

    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
    /*
    此实现执行此上下文的底层 bean 工厂的实际刷新,关闭先前的 bean 工厂(如果有)并为上下文生命周期的下一阶段初始化一个新的 bean 工厂。
    */
    @Override
    protected final void refreshBeanFactory() throws BeansException {
    // 如果有 Bean工厂,则关闭该工厂
    if (hasBeanFactory()) {
    destroyBeans();
    closeBeanFactory();
    }
    try {
    // 创建一个新bean工厂,这里的DefaultListableBeanFactory就是前面的Spring核心类,这个类真的很重要!
    DefaultListableBeanFactory beanFactory = createBeanFactory();
    // 序列化指定ID,如果需要的话,让这个BeanFactory从ID反序列化掉BeanFactory对象
    beanFactory.setSerializationId(getId());
    // 自定义此上下文使用的内部 bean 工厂。为每次 refresh() 尝试调用。默认实现应用此上下文
    // 的“allowBeanDefinitionOverriding”和“allowCircularReferences”设置(如果指定)。
    // 可以在子类中重写以自定义任何DefaultListableBeanFactory 的设置。
    customizeBeanFactory(beanFactory);
    // 加载bean定义信息,这一步实际上就从XML配置文件里的bean信息给读取到了Factory里了。
    loadBeanDefinitions(beanFactory);
    this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
    throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
    }

    /*
    确定此上下文当前是否包含 bean 工厂,即至少已刷新一次且尚未关闭。
    */
    protected final boolean hasBeanFactory() {
    return (this.beanFactory != null);
    }

    /*
    关闭BeanFactory实例
    */
    @Override
    protected final void closeBeanFactory() {
    DefaultListableBeanFactory beanFactory = this.beanFactory;
    if (beanFactory != null) {
    beanFactory.setSerializationId(null);
    this.beanFactory = null;
    }
    }

    image-20220209162635420

    image-20220209162728047

    ​ 上面图片,是loadBeanDefinitions()方法运行完之后,eanFactory变量里面存放着一个ConcurrentHashMap变量,用于存放着person这个KV键值对,Key为person,Value为一个ArrayList的变量,里面存放着person的两个属性:age、name。下面接着深入该方法分析

    1. loadBeanDefinitions(AbstractXmlApplicationContext.class

    ​ BeanDefinition,顾名思义,用于定义bean信息的类,包含bean的class类型、构造参数、属性值等信息,每个bean对应一个BeanDefinition的实例。简化BeanDefinition仅包含bean的class类型。

    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
    /*
    通过 XmlBeanDefinitionReader 加载 bean 定义。
    */
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 为给定的 BeanFactory 创建一个新的 XmlBeanDefinitionReader。
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // 使用此上下文的资源加载环境配置 bean 定义阅读器。
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    // 设置 ResourceLoader 以用于资源定位。
    beanDefinitionReader.setResourceLoader(this);
    // 设置要用于解析的 SAX 实体解析器。默认情况下,将使用 ResourceEntityResolver。
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // 允许子类提供阅读器的自定义初始化
    initBeanDefinitionReader(beanDefinitionReader);
    // 实际加载 bean 定义。
    loadBeanDefinitions(beanDefinitionReader);
    }

    /*
    AbstractApplicationContext.class
    以可配置的形式返回此应用程序上下文的环境,允许进一步定制。
    如果未指定,则将通过 createEnvironment() 初始化默认环境。
    */
    @Override
    public ConfigurableEnvironment getEnvironment() {
    if (this.environment == null) {
    this.environment = createEnvironment();
    }
    return this.environment;
    }

    /*
    XmlBeanDefinitionReader.class
    */
    public void setEntityResolver(@Nullable EntityResolver entityResolver) {
    this.entityResolver = entityResolver;
    }

    /*
    初始化用于加载此上下文的 bean 定义的 bean 定义阅读器。默认实现为空。
    可以在子类中被覆盖,例如用于关闭 XML 验证或使用不同的 XmlBeanDefinitionParser 实现。
    */
    protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
    reader.setValidating(this.validating);
    }
  3. loadBeanDefinitions(AbstractXmlApplicationContext.class

    ​ 注意这个和上个不一样,是重载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /*
    使用给定的 XmlBeanDefinitionReader 加载 bean 定义。
    bean 工厂的生命周期由 refreshBeanFactory 方法处理;因此这个方法只是应该加载和或注册 bean 定义。
    */
    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); // <-------是string路径会执行这个
    }
    }
  4. loadBeanDefinitions(AbstractBeanDefinationReader.class

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

    /*
    从指定的资源位置加载 bean 定义。位置也可以是位置模式,
    前提是此 bean 定义读取器的 ResourceLoader 是 ResourcePatternResolver。
    */
    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) {
    // 资源模式匹配可用。
    try {
    Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
    // 从指定的 XML 文件加载 bean 定义。这里debug会进去XmlBeanDefinitionReader,
    int count = loadBeanDefinitions(resources);
    if (actualResources != null) {
    Collections.addAll(actualResources, resources);
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
    }
    return count;
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(
    "Could not resolve bean definition resource pattern [" + location + "]", ex);
    }
    }
    else {
    // 只能通过绝对 URL 加载单个资源。
    Resource resource = resourceLoader.getResource(location);
    int count = loadBeanDefinitions(resource);
    if (actualResources != null) {
    actualResources.add(resource);
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
    }
    return count;
    }
    }
  5. getResources(PathMatchingResourcePatternResolver.class

    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
    @Override
    public Resource[] getResources(String locationPattern) throws IOException {
    Assert.notNull(locationPattern, "Location pattern must not be null");
    if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
    // 类路径资源(可能有多个同名资源)
    if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
    // 类路径资源模式
    return findPathMatchingResources(locationPattern);
    }
    else {
    // 具有给定名称的所有类路径资源
    return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
    }
    }
    else {
    // 通常只在前缀后面查找一个模式,并且在Tomcat之后只有“* /”分隔符之后的“war:”协议。
    int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
    locationPattern.indexOf(':') + 1);
    if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
    // 文件模式
    return findPathMatchingResources(locationPattern);
    }
    else {
    // 具有给定名称的单个资源
    return new Resource[] {getResourceLoader().getResource(locationPattern)};
    }
    }
    }
  6. loadBeanDefinitions(XmlBeanDefinitionReader.class

    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
    /*
    从XML配置文件中获取bean定义信息
    */
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    ...
    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
    currentResources = new HashSet<>(4);
    this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    ...
    try {
    InputStream inputStream = encodedResource.getResource().getInputStream();
    try {
    InputSource inputSource = new InputSource(inputStream);
    if (encodedResource.getEncoding() != null) {
    inputSource.setEncoding(encodedResource.getEncoding());
    }
    //获取到读取xml配置文件的InputStream流后,进行BeanDefinitions的加载
    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    finally {
    inputStream.close();
    }
    }
    catch (IOException ex) {
    ...
    }
    finally {
    currentResources.remove(encodedResource);
    if (currentResources.isEmpty()) {
    this.resourcesCurrentlyBeingLoaded.remove();
    }
    }
    }

    /*
    真正从xml配置文件中加载Bean定义信息
    */
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {

    try {
    //获取xml的配置信息并封装为Document对象
    Document doc = doLoadDocument(inputSource, resource);
    return this.registerBeanDefinitions(doc, resource);
    }
    catch (BeanDefinitionStoreException ex) {
    ...
    }
    }

    以上的流程是在读取BeanDefinition信息,下面看如何将其注册

image-20220210174705211

  1. registerBeanDefinitions(XmlBeanDefinitionReader.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /*
    注册包含在给定 DOM 文档中的 bean 定义
    */
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    // 创建 BeanDefinitionDocumentReader 以用于从 XML 文档中实际读取 bean 定义
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    // 注册表中定义的 bean 数量
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 打开一个 DOM 文档;然后初始化在 <beans> 级别指定的默认设置;然后解析包含的 bean 定义。
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); // <-----------
    return getRegistry().getBeanDefinitionCount() - countBefore;
    }
  2. registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.class

    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
    /*
    注册并解析包含的 bean 定义。
    */
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    doRegisterBeanDefinitions(doc.getDocumentElement());
    }

    /*
    在给定的根 <beans> 元素中注册每个 bean 定义。
    */
    protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.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.isDebugEnabled()) {
    logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
    "] not matching: " + getReaderContext().getResource());
    }
    return;
    }
    }
    }

    preProcessXml(root);
    // 解析beanDefinitions信息,经过这个方法,beanFactory中就会保存从xml配置文件中解析而来的信息
    parseBeanDefinitions(root, this.delegate);
    postProcessXml(root);

    this.delegate = parent;
    }

    /*
    解析文档中根级别的元素:“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);
    }
    }

    /*
    解析默认元素
    */
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
    importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
    processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    // 读取到xml配置文件的<bean>节点
    processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    // 递归
    doRegisterBeanDefinitions(ele);
    }
    }

    /*
    处理给定的 bean 元素,解析 bean 定义并将其注册到注册表。
    */
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); // 解析提供的 <bean> 元素
    if (bdHolder != null) {
    bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); // 如果适用,通过命名空间处理程序装饰给定的 bean 定义。
    try {
    // 注册最终的装饰实例。
    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));
    }
    }
  3. parseBeanDefinitionElement(BeanDefinitionParserDelegate.class

    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
    @Nullable
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return parseBeanDefinitionElement(ele, null);
    }

    /*
    解析提供的 <bean> 元素。
    */
    @Nullable
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
    String id = ele.getAttribute(ID_ATTRIBUTE);
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    List<String> aliases = new ArrayList<>();
    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.isTraceEnabled()) {
    logger.trace("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.isTraceEnabled()) {
    logger.trace("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;
    }

    /*
    解析 bean 定义本身,而不考虑名称或别名。如果在解析 bean 定义期间出现问题,则可能返回 null。
    */
    @Nullable
    public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, @Nullable BeanDefinition containingBean) {

    this.parseState.push(new BeanEntry(beanName));

    String className = null;
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
    className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }
    String parent = null;
    if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
    parent = ele.getAttribute(PARENT_ATTRIBUTE);
    }

    try {
    // 创建BeanDefinition
    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);
    // 通过property的value解析值吗,本文的程序xml就是通过property属性设置bean的值的,最终被这一方法所解析出来。
    parsePropertyElements(ele, bd);
    parseQualifierElements(ele, bd);

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

    return bd;
    }
    catch (ClassNotFoundException ex) {
    error("Bean class [" + className + "] not found", ele, ex);
    }
    catch (NoClassDefFoundError err) {
    error("Class that bean class [" + className + "] depends on not found", ele, err);
    }
    catch (Throwable ex) {
    error("Unexpected failure during bean definition parsing", ele, ex);
    }
    finally {
    this.parseState.pop();
    }

    return null;
    }

    // 解析给定 bean 元素的属性子元素。
    public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
    Node node = nl.item(i);
    if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
    // 解析出参数值来,这里就真正的讲age的23,和name的bruis值解析出来并防止在一个组装的类里面存放着。
    // 因为这里有两个bean,所以要循环调用两次parsePropertyElement()方法
    parsePropertyElement((Element) node, bd);
    }
    }
    }

    // 解析属性元素
    public void parsePropertyElement(Element ele, BeanDefinition bd) {
    String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
    if (!StringUtils.hasLength(propertyName)) {
    error("Tag 'property' must have a 'name' attribute", ele);
    return;
    }
    this.parseState.push(new PropertyEntry(propertyName));
    try {
    if (bd.getPropertyValues().contains(propertyName)) {
    error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
    return;
    }
    Object val = parsePropertyValue(ele, bd, propertyName);
    PropertyValue pv = new PropertyValue(propertyName, val);
    parseMetaElements(ele, pv);
    pv.setSource(extractSource(ele));
    // 就是这一步,将K为age、name,值分别为23、bruis的KV对存放在了Spring容器里。
    bd.getPropertyValues().addPropertyValue(pv);
    }
    finally {
    this.parseState.pop();
    }
    }

总结:该方法实际上实现了容器的初始化以及BeanDefinition的注册与加载,方便后续Bean的创建和加载

容器的初始化过程如下:

  • 第一个过程是Resource定位过程。这个Resource定位过程指的是BeanDefinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用都提供了统一接口。这个定位过程类似于容器寻找数据的过程,就像使用水桶装水先要把水找到一样。
  • 第二个过程是BeanDefinition的载入。这个载入过程是把用户定义好的Bean表示成IOC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。下面介绍这个数据结构的详细定义。具体来说,这个BeanDefinition实际上就是POJO对象在IOC容器的抽象,通过这个BeanDefinition定义的数据结构,使IOC能够方便地对POJO对象进行管理。
  • 第三个过程是向IOC容器注册这些BeanDefinition的过程,这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的。这个注册过程把载入过程中解析到的BeanDefinition向IOC容器进行注册。通过上面的分析,我们知道IOC内部将BeanDefinition注册到了ConcurrentHashMap中。

3.5 prepareBeanFactory

  1. prepareBeanFactory(AbstractApplicationContext.class

    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
    /*
    配置工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器
    */
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 告诉内部 bean 工厂使用上下文的类加载器等。
    beanFactory.setBeanClassLoader(getClassLoader());
    if (!shouldIgnoreSpel) {
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    }
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 使用上下文回调配置 bean 工厂。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

    // BeanFactory 接口未在普通工厂中注册为可解析类型。
    // MessageSource 作为 bean 注册(并为自动装配找到)。
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 将用于检测内部 bean 的早期后处理器注册为 ApplicationListener。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 检测 LoadTimeWeaver 并准备编织(如果找到)。
    if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    // 为类型匹配设置一个临时 ClassLoader。
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册默认环境 bean。
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
    beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
    }

3.6 postProcessBeanFactory

  1. postProcessBeanFactory(AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    /*
    在标准初始化之后修改应用程序上下文的内部 bean 工厂。所有 bean 定义都将被加载,
    但还没有 bean 被实例化。这允许在某些 ApplicationContext 实现中注册特殊的 BeanPostProcessors 等。
    简单来说,就是允许我们在bean实例化之前修改bean的定义信息即BeanDefinition的信息
    */
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

3.7 invokeBeanFactoryPostProcessors

  1. invokeBeanFactoryPostProcessors (AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 实例化并调用所有已注册的 BeanFactoryPostProcessor bean,如果给定,则尊重显式顺序。必须在单例实例化之前调用。
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    }

3.8 registerBeanPostProcessors

  1. registerBeanPostProcessors (AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    /*
    实例化并注册所有 BeanPostProcessor bean,如果给定,则尊重显式顺序。必须在应用程序 bean 的任何实例化之前调用。
    */
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

3.9 initMessageSource

  1. initMessageSource(AbstractApplicationContext.class

    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 void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
    this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
    // 使 MessageSource 感知父 MessageSource。
    if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
    HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
    if (hms.getParentMessageSource() == null) {
    // 如果尚未注册父消息源,则仅将父上下文设置为父消息源。
    hms.setParentMessageSource(getInternalParentMessageSource());
    }
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Using MessageSource [" + this.messageSource + "]");
    }
    }
    else {
    // 使用空 MessageSource 能够接受 getMessage 调用。
    DelegatingMessageSource dms = new DelegatingMessageSource();
    dms.setParentMessageSource(getInternalParentMessageSource());
    this.messageSource = dms;
    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    if (logger.isTraceEnabled()) {
    logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
    }
    }
    }

3.10 initApplicationEventMulticaster

  1. initApplicationEventMulticaster(AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*
    初始化 ApplicationEventMulticaster。如果上下文中没有定义,则使用 SimpleApplicationEventMulticaster。
    */
    protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
    this.applicationEventMulticaster =
    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    if (logger.isTraceEnabled()) {
    logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
    }
    }
    else {
    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    if (logger.isTraceEnabled()) {
    logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
    "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
    }
    }
    }

3.11 onRefresh

  1. onRefresh(AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    /*
    可以重写以添加特定于上下文的刷新工作的模板方法。在单例实例化之前调用特殊 bean 的初始化。这个实现是空的。
    */
    protected void onRefresh() throws BeansException {
    // 对于子类:默认情况下什么都不做。
    }

3.12 registerListeners

  1. registerListeners(AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    protected void registerListeners() {
    // 首先注册静态指定的监听器。
    for (ApplicationListener<?> listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 不要在这里初始化 FactoryBeans:我们需要让所有常规 bean 保持未初始化状态,以让后处理器应用于它们!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期应用程序事件,因为我们终于有了一个多播器......
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
    for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
    getApplicationEventMulticaster().multicastEvent(earlyEvent);
    }
    }
    }

3.12 finishBeanFactoryInitialization

image-20220210173837998

  1. finishBeanFactoryInitialization(AbstractApplicationContext.class

    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
    /*
    完成此上下文的 bean 工厂的初始化,初始化所有剩余的单例 bean。
    */
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 为此上下文初始化转换服务。
    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));
    }

    // 如果之前没有注册过任何 BeanFactoryPostProcessor(例如 PropertySourcesPlaceholderConfigurer bean),
    // 则注册一个默认的嵌入值解析器:此时,主要用于解析注释属性值。
    if (!beanFactory.hasEmbeddedValueResolver()) {
    beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 尽早初始化 LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
    getBean(weaverAwareName);
    }

    // 停止使用临时 ClassLoader 进行类型匹配。
    beanFactory.setTempClassLoader(null);

    // 允许缓存所有 bean 定义元数据,而不是期望进一步的更改。
    beanFactory.freezeConfiguration();

    // 实例化所有剩余的(非惰性初始化)单例。
    beanFactory.preInstantiateSingletons();
    }

    ​ 这里的懒加载的意思,指的是bean单例不是在Spring容器初始化的时候就创建的,而是在要使用该bean的时候,才会创建该bean。

  2. preInstantiateSingletons(DefaultListableBeanFactory.class

    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
    @Override
    public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
    logger.trace("Pre-instantiating singletons in " + this);
    }

    // 迭代一个副本以允许 init 方法依次注册新的 bean 定义。
    // 虽然这可能不是常规工厂引导程序的一部分,但它确实可以正常工作。
    // 获取所有的bean定义的名字,并保存在集合List里面。
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 触发所有非延迟单例bean的初始化...
    for (String beanName : beanNames) {
    // 触发所有适用bean的后初始化回调
    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) {
    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) {
    getBean(beanName);
    }
    }
    }
    else {
    getBean(beanName);
    }
    }
    }

    // 为所有适用的 bean 触发初始化后回调...
    for (String beanName : beanNames) {
    Object singletonInstance = getSingleton(beanName);
    if (singletonInstance instanceof SmartInitializingSingleton) {
    StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
    .tag("beanName", beanName);
    SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    smartSingleton.afterSingletonsInstantiated();
    return null;
    }, getAccessControlContext());
    }
    else {
    smartSingleton.afterSingletonsInstantiated();
    }
    smartInitialize.end();
    }
    }
    }
  3. getBean(AbstractBeanFactory.class

    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
    @Override
    public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
    }

    /*
    返回指定 bean 的一个实例,该实例可以是共享的,也可以是独立的。
    */
    protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
    // 去除name上存在的工厂bean的前缀
    String beanName = transformedBeanName(name);
    Object beanInstance;

    // 快速判断单例缓存中是否存在该bean,如果存在则返回单例bean;否则返回null
    Object sharedInstance = getSingleton(beanName); // <--------------
    if (sharedInstance != null && args == null) {
    if (logger.isTraceEnabled()) {
    if (isSingletonCurrentlyInCreation(beanName)) {
    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
    "' that is not fully initialized yet - a consequence of a circular reference");
    }
    else {
    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
    }
    }
    // 从单例缓存中获取单例bean
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
    // 如果我们已经在创建这个 bean 实例,则失败:我们可能在循环引用中。
    if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
    }

    // 检查此工厂中是否存在 bean 定义。
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // 未找到 -> 检查父级。
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
    nameToLookup, requiredType, args, typeCheckOnly);
    }
    else if (args != null) {
    // 使用显式参数委托给父级。
    return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else if (requiredType != null) {
    // 没有 args -> 委托给标准 getBean 方法。
    return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    else {
    return (T) parentBeanFactory.getBean(nameToLookup);
    }
    }

    if (!typeCheckOnly) {
    markBeanAsCreated(beanName); // 将指定的 bean 标记为已创建(或即将创建)。这允许 bean 工厂优化其缓存以重复创建指定的 bean
    }

    StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
    .tag("beanName", name);
    try {
    if (requiredType != null) {
    beanCreation.tag("beanType", requiredType::toString);
    }
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    // 保证当前 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 {
    getBean(dep);
    }
    catch (NoSuchBeanDefinitionException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    }
    }
    }

    // 创建 bean 实例。
    if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
    try {
    return createBean(beanName, mbd, args); // < -----------------
    }
    catch (BeansException ex) {
    // 从单例缓存中显式删除实例:它可能已被创建过程急切地放在那里,以允许循环引用解析。
    // 还要删除任何接收到对 bean 的临时引用的 bean。
    destroySingleton(beanName);
    throw ex;
    }
    });
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
    // 这是一个原型 -> 创建一个新实例。
    Object prototypeInstance = null;
    try {
    beforePrototypeCreation(beanName);
    prototypeInstance = createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else {
    String scopeName = mbd.getScope();
    if (!StringUtils.hasLength(scopeName)) {
    throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
    }
    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, () -> {
    beforePrototypeCreation(beanName);
    try {
    return createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    });
    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
    throw new ScopeNotActiveException(beanName, scopeName, ex);
    }
    }
    }
    catch (BeansException ex) {
    beanCreation.tag("exception", ex.getClass().toString());
    beanCreation.tag("message", String.valueOf(ex.getMessage()));
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
    }
    finally {
    beanCreation.end();
    }
    }

    return adaptBeanInstance(name, beanInstance, requiredType);
    }
  4. getSingleton(DefaultSingletonBeanRegistry.class

    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
    @Override
    @Nullable
    public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
    }

    /*
    返回在给定名称下注册的(原始)单例对象。
    检查已经实例化的单例,还允许对当前创建的单例进行早期引用(解决循环引用)。
    */
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 快速检查没有完整单例锁的现有实例
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    singletonObject = this.earlySingletonObjects.get(beanName);
    if (singletonObject == null && allowEarlyReference) {
    synchronized (this.singletonObjects) {
    // 在完整的单例锁中一致地创建早期引用
    singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null) {
    singletonObject = this.earlySingletonObjects.get(beanName);
    if (singletonObject == null) {
    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    if (singletonFactory != null) {
    singletonObject = singletonFactory.getObject();
    this.earlySingletonObjects.put(beanName, singletonObject);
    this.singletonFactories.remove(beanName);
    }
    }
    }
    }
    }
    }
    return singletonObject;
    }
  5. createBean(AbstractAutowireCapableBeanFactory.class

    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
    /*
    此类的中心方法:创建 bean 实例、填充 bean 实例、应用后处理器等。
    */
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
    logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // 确保此时实际解析了 bean 类,并克隆 bean 定义以防动态解析的 Class 无法存储在共享的合并 bean 定义中。
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
    }

    // 准备方法覆盖
    try {
    mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    beanName, "Validation of method overrides failed", ex);
    }

    try {
    // 调用实例化前的后置处理器,在这个后置处理器中可以对bean进行处理,可以返回由后置处理器处理的bean而不是被实例化的bean。
    // 换句话说就是这里可以拦截住bean的实例化
    // Spring的后置处理器后面有机会再专门写一篇博文来总结学习一下
    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);
    }

    try {
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isTraceEnabled()) {
    logger.trace("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    // 先前检测到的异常已经具有正确的 bean 创建上下文,或者要与 DefaultSingletonBeanRegistry 通信的非法单例状态。
    throw ex;
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
    }

    /*
    正在的创建一个bean,并且按照配置文件的配置来实例化该bean。如果没有初始化前的后置处理器的调用,则调用该方法。
    */
    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    // 创建一个包装类,用于包装真正要创建的bean。
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
    // 使用适当的实例化策略例如:工厂方法、构造函数自动装配或者简单实例化 来为指定bean创建新的实例。
    // 这里仅仅是简单的实例化,为bean设置默认初始值
    // 也就是name为null,age为0。此时instanceWrapper任然还只是一个包装bean,并不是一个真正意义上的person类bean。
    // 1. 实例化
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 终于,我们千辛万苦打断点调试来到了这一步,就是这一步, 获得了我们想要的person类bean。
    // 只需要在BeanWrapper里取出WrapperInstance即可。
    // 接下来就是要拿这个创建好的bean和BeanDefinition进行实例化了。
    Object bean = instanceWrapper.getWrappedInstance();
    // 获取bean的类型
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
    }

    // 调用后置处理器去修改bean的定义信息。
    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;
    }
    }

    // 即使被 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));
    }

    // 实例化一个真正使用的bean。
    Object exposedObject = bean;
    try {
    // 2. 属性赋值
    populateBean(beanName, mbd, instanceWrapper); // <--------------------
    // 3. 初始化
    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(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 " +
    "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
    }
    }
    }
    }

    // 销毁注册回调接口
    try {
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
    }

    /*
    使用 bean 定义中的属性值填充给定 BeanWrapper 中的 bean 实例。
    */
    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;
    }
    }

    // 让任何 InstantiationAwareBeanPostProcessors 有机会在设置属性之前修改 bean 的状态。
    // 例如,这可以用于支持字段注入的样式。
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    return;
    }
    }
    }
    // 取出BeanDefinition里的属性值
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    // 如果设置的是自动装配模式,则由自动装配来进行赋值
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    // 通过bean名自动装配
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    autowireByName(beanName, mbd, bw, newPvs);
    }
    // 通过bean类型自动装配
    if (resolvedAutowireMode == 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 (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    if (pvsToUse == null) {
    if (filteredPds == null) {
    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    }
    pvsToUse = bp.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);
    }
    // 这里的PropertyValues已经包含了bean字段属性的设置值了
    if (pvs != null) {
    applyPropertyValues(beanName, mbd, bw, pvs);
    }
    }

    /*
    应用给定的属性值,解析对此 bean 工厂中其他 bean 的任何运行时引用。必须使用深拷贝,所以我们不会永久修改这个属性。
    */
    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);

    // 拷贝值;创建一个深拷贝副本,应用于任何bean引用此bean的情况。
    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();
    if (originalValue == AutowiredPropertyMarker.INSTANCE) {
    Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
    if (writeMethod == null) {
    throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
    }
    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
    }
    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);
    }
    // 可能在合并的bean定义中存储转换后的值,以避免为每个创建的bean实例重新转换。
    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();
    }

    // 将深拷贝属性数组填充到beanWrapper中。这里就真正的将属性值填充到了bean上,实现了
    try {
    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
    }

3.13 finishRefresh

  1. finishRefresh(AbstractApplicationContext.class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*
    完成此上下文的刷新,调用 LifecycleProcessor 的 onRefresh() 方法并发布 ContextRefreshedEvent。
    */
    protected void finishRefresh() {
    // 清除上下文级别的资源缓存(例如扫描中的 ASM 元数据)。
    clearResourceCaches();

    //为此上下文初始化生命周期处理器。
    initLifecycleProcessor();

    // 首先将刷新传播到生命周期处理器。
    getLifecycleProcessor().onRefresh();

    // 发布最终事件。
    publishEvent(new ContextRefreshedEvent(this));

    // 参与 LiveBeansView MBean(如果处于活动状态)。
    if (!NativeDetector.inNativeImage()) {
    LiveBeansView.registerApplicationContext(this);
    }
    }

​ 经过上面的分析,就知道真正的对bean赋值填充是在AbstractAutowireCapableBeanFactory.class类里的applyPropertyValues方法里的,并且是通过对原属性值进行了一次深拷贝,然后将深拷贝后的属性值填充到bean里的。

4. 总结

​ 本次源码分析,主要还是对容器的创建与初始化进行分析,也就是obtainFreshBeanFactory finishBeanFactoryInitialization这两个函数,其他函数是对其的加工或者预处理,留到后面再详细展开。

参考

(99条消息) Spring和Spring Framework的理解_海TAO的博客-CSDN博客_springframework和spring

JavaSourceCodeLearning/深入Spring源码系列(二)——深入Spring容器,通过源码阅读和时序图来彻底弄懂Spring容器(上)


Spring源码阅读(一)
https://2w1nd.github.io/2022/02/08/框架/Spring/Spring源码阅读(一)/
作者
w1nd
发布于
2022年2月8日
许可协议