Spring启动流程(大纲篇)

Spring启动流程

本文来盘一盘Spring的启动流程

Spring启动流程过于复杂,如果所有的细节都集中在一篇文章,那是不可能的😂

本文更多的只是一个带你走一遍大致的流程

有些环节的具体执行细节后续会有衍生文章做单独分析,有衍生文章的我都在标题处标注了❗

搭建环境

使用maven创建一个新项目

在这里插入图片描述

引入Spring依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

Spring配置文件

<?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">

</beans>

实体类

package com.zhima;

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

启动类

在打印cpa的那行打上断点

package com.zhima;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext cpa = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(cpa);
    }
}

配置一个类型为Student的bean

在applicationContext.xml中添加以下标签

<bean id="student" class="com.zhima.Student"/>

调试方式启动查看容器

可以看到容器内已经有了一些bean了,也看到了我们自己配置的student的bean

在这里插入图片描述

找入口

基于XML的Spring容器的入口比较好找

就是ClassPathXmlApplicationContext的构造方法

继承体系

看一下它的继承体系

在这里插入图片描述

它的继承体系十分庞大,但是不要慌,主要的父类就四个

  • AbstractApplicationContext
  • AbstractRefreshableApplicationContext
  • AbstractRefreshableConfigApplicationContext
  • AbstractXmlApplicationContext

打断点

ClassPathXmlApplicationContext

在这里插入图片描述

可以看到调用了三个参数的构造方法

在这里插入图片描述

refresh方法就是Spring启动流程中最最核心的方法

这个方法是在其父类AbstractApplicationContext中的,接下来就围绕着这个方法开始分析

prepareRefresh

见函数名知意,此方法就是为refresh做准备

在这里插入图片描述

obtainFreshBeanFactory

在这里插入图片描述

在这里插入图片描述

AbstractRefreshableApplicationContext#refreshBeanFactory

在这里插入图片描述

AbstractXmlApplicationContext#loadBeanDefinitions

在这里插入图片描述

❗AbstractXmlApplicationContext#loadBeanDefinitions

在这里插入图片描述

XmlBeanDefinitionReader解析xml的过程会放在衍生文章《Spring启动流程-解析XML》里面

这里只需要知道它将xml中我们定义的那些bean转化成了BeanDefinition对象

还记得刚刚创建读取器的时候传入了beanfactory吗

在这里插入图片描述

这个时候读取器加载的这些BeanDefinition对象已经在beanfactory中了

prepareBeanFactory

在这里插入图片描述

在这里插入图片描述

postProcessBeanFactory

给子类的拓展点,用来做一些beanFactory初始化后的一些工作

在这里插入图片描述

❗invokeBeanFactoryPostProcessors

在这里插入图片描述

在BeanFactory根据BeanDefinitions创建对象之前,需要经过一些BeanFactoryProcessor的postProcessBeanFactory方法

ConfigurationClassPostProcessor


为什么已经有postProcessBeanFactory拓展点了还需要有BeanFactoryPostProcessor?

它两提供拓展点的对象不同

postProcessBeanFactory是给子类容器拓展的

BeanFactoryPostProcessor是给用户拓展的

❗registerBeanPostProcessors

注册可以介入bean创建的BeanPostProcessor实例

在这里插入图片描述

可以看到这里也是调用的PostProcessorRegistrationDelegate的静态方法

和刚刚invokeBeanFactoryPostProcessors中调用的是同一个类

这两块的分析会放在衍生篇《Spring启动流程-后处理器》

initMessageSource

MessageSource是用于国际化的

如果用户注册了一个MESSAGE_SOURCE_BEAN_NAME(messageSource)的Bean,就会使用用户自定义的

否则就使用默认的DelegatingMessageSource

在这里插入图片描述

❗initApplicationEventMulticaster

Spring的事件发布组播器

和初始化messageSource的逻辑很像

先看用户有没有定义beanName是APPLICATION_EVENT_MULTICASTER_BEAN_NAME(applicationEventMulticaster)的Bean

有的话就使用用户定义的

否则就使用SimpleApplicationEventMulticaster

在这里插入图片描述

Spring的事件机制会在衍生篇《Spring启动流程-事件》

onRefresh

在这里插入图片描述

registerListeners

注册监听器

在这里插入图片描述

❗finishBeanFactoryInitialization

ConversionService是用来做类型转换工作的,和刚刚初始化messageSource的动作很像,也是先看用户有没有自定义

有则用之,无则默认

在这里插入图片描述

beanFactory.preInstantiateSingletons是真正执行创建Bean的方法

Spring的Bean的生命周期会在衍生篇《Spring启动流程-Bean生命周期》

finishRefresh

在这里插入图片描述

initLifecycleProcessor

在这里插入图片描述

LifecycleProcessor

来看看这个LifecycleProcessor到底是何方神圣

它是一个Lifecycle的子接口

在这里插入图片描述

在这里插入图片描述

这个Lifecycle不知道大家还有没有印象了,在ClassPathXmlApplicationContext的继承体系中出现过

在这里插入图片描述

并且实现了接口

在这里插入图片描述

那这个start是谁来调用的呢?就是这个LifecycleProcessor!

finishRefresh中往下看

在这里插入图片描述

现在我们没有自定义LifecycleProcessor,所以我们来看看他默认的实现类DefaultLifecycleProcessoronRefresh中做了些什么

在这里插入图片描述

在这里插入图片描述

本人技术水平有限,文章中难免会出现错误,读者如有发现,感谢各位指正!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝麻\n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值