Springboot启动流程详解

SpringMVC请求流程详解

SpringMVC框架是一个基于请求驱动的Web框架,并且使用了‘前端控制器’模型来进行设计,再根据‘请求映射规则’分发给相应的页面控制器进行处理。

(一)整体流程

在这里插入图片描述

每一个SpringBoot程序都有一个主入口,这个主入口就是main方法,而main方法中都会调用SpringBootApplication.run方法,一个快速了解SpringBootApplication启动过程的好方法就是在run方法中打一个断点,然后通过Debug的模式启动工程,逐步跟踪了解SpringBoot源码是如何完成环境准备和启动加载bean的。

查看SpringBootApplication.run方法的源码就可以发现SpringBoot启动的流程主要分为两大阶段:

初始化SpringApplication运行SpringApplication
运行SpringApplication的过程
其中运行SpringApplication的过程又可以细分为以下几个部分:

1)SpringApplicationRunListeners 引用启动监控模块

2)ConfigrableEnvironment配置环境模块和监听:包括创建配置环境、加载属性配置文件和配置监听

3)ConfigrableApplicationContext配置应用上下文:包括配置应用上下文对象、配置基本属性和刷新应用上下文

在这里插入图片描述

2 初始化SpringApplication
步骤1进行SpringApplication的初始化,配置基本的环境变量、资源、构造器、监听器,初始化阶段的主要作用是为运行SpringApplication实例对象启动环境变量准备以及进行必要的资源构造器的初始化动作,代码如下:

public SpringApplication(ResourceLoader resourceLoader, Object... sources){
    this.resourceLoader = resourceLoader;
    initialize(source);
}

@SupressWarnings({"unchecked","rowtypes"})
private void initialize(Object[] sources){
    if(sources != null && sources.length > 0){
        this.sources.addAll(Arrays.asList(sources));
    }
    this.WebEnvironment = deduceWebEnvironment;
    setInitiallizers((Collection) getSpringFactoriesInstances(ApplicationContextInitiallizer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}
SpringApplication方法的核心就是this.initialize(sources)初始化方法,SpringApplication通过调用该方法完成初始化工作。deduceWebEnvironment方法用来判断当前应用的环境,该方法通过获取两个类来判断当前环境是否是Web环境。而getSpringFactoriesInstances方法主要用来从spring.factories文件中找出KeyApplicationContextInitiallizer的类并实例化,然后调用setInitiallizer方法设置到SpringApplication的initiallizer属性中,找到它所有应用的初始化器。接着调用setListener方法设置应用监听器,这个过程可以找到所有应用程序的监听器,然后找到应用启动主类名称。
3 运行SpringApplication
SpringBoot正式启动加载过程,包括启动流程监控模块、配置环境加载模块、ApplicationContext容器上下文环境加载模块。refreshContext方法刷新应用上下文并进行自动化配置模块加载,也就是上文提到的SpringFactoriesLoader根据指定classpath加载META-INF/spring.factories文件的配置,实现自动配置核心功能。运行SpringApplication的主要代码如下:

public ConfigurableApplicationContext run(String... args) {
    ConfigurableApplicationContext context = null;
    FailureAnalyzer analyzer = null;
    configureHeadlessProperty();
    // 步骤1
    SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
    try{
        // 步骤2
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        Banner printBanner = printBanner(environment);
        // 步骤3
        context = createApplicationContext();
        prepareContext(context, environment, listeners, applicationArguments, printBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        listeners.finished(context, null);
        // 省略
        return context;
    }
}
3.1 SpringApplciationRunListener应用启动监控模块

应用启动监控模块对应上述源码中的注释步骤1到步骤2之间的两行代码,它创建了应用的监听器SpringApplicationRunListeners并开始监听,监控模块通过调用getSpringFactoriesInstances私有协议从META-INF/spring.factories文件中取得SpringApplicationRunListener监听器实例。

当前事件监听器SpringApplicationRunListener中只有一个EventPublishingRunlistener广播事件监听器,它的starting方法会封装成SpringApplicatiionEvent事件广播出去,被SpringApplication中配置的listener监听。这一步骤执行完成后也会同时通知SpringBoot其他模块目前监听初始化已经完成,可以开始执行启动方案了。

3.2 ConfigurableEnviroment 配置环境模块和监听

对应上述源码注释中的步骤2到步骤3之间的几行代码,下面分解步骤说明:

(1) 创建配置环境,创建应用程序的环境信息。如果是Web程序,创建StandardServletEnvironment;否则创建StandardEnviroment(2) 加载属性配置文件,将配置文件加入监听器对象中(SpringApplicationRunListeners)。通过configPropertySource方法设置properties配置文件,通过执行configProfies方法设置profiles;

(3) 配置监听,发布environmentPrepared事件,及调用ApplicationListener#onApplicationEvent方法,通知SpringBoot应用的environment已经准备完成。

3.3  ConfigurableApplicationContext配置应用上下文

对应源码中的步骤3下面的几行代码,下面分解步骤说明:

(1)配置Spring容器应用上下文对象,它的作用是创建Run方法的返回对象ConfigurableApplicationContext(应用配置上下文),此类主要继承了ApplicationLifeCycleCloseable接口,而ApplicationContextSpring框架中负责Bean注入容器的主要载体,负责bean加载、配置管理、维护bean之间依赖关系及Bean生命周期管理。

(2)配置基本属性,对应prepareContext方法将listener、environment、banner、applicationArguments等重要组件与Spring容器上下文对象关联。借助SpringFactoriesLoader查找可用的ApplciationContextInitailizer, 它的initialize方法会对创建好的ApplicationContext进行初始化,然后它会调用SpringApplicationRunListener#contextPrepared方法,此时SpringBoot应用的ApplicationContext已经准备就绪,为刷新应用上下文准备好了容器。

(3)刷新应用上下文,对应源码中的refreshContext(context)方法将通过工程模式产生应用上下文中所需的bean。实现spring-boot-starter-*(mybatis、redis等)自动化配置的关键,包括spring.factories的加载、bean的实例化等核心工作。然后调用SpringApplicationRunListener#finish方法告诉SprignBoot应用程序,容器已经完成ApplicationContext装载。
SpringBoot应用程序的启动流程主要包括初始化SpringApplication和运行SpringApplication两个过程。其中初始化SpringApplication包括配置基本的环境变量、资源、构造器和监听器,为运行SpringApplciation实例对象作准备;而运行SpringApplication实例为应用程序正式启动加载过程,包括SpringApplicationRunListeners  引用启动监控模块、ConfigrableEnvironment配置环境模块和监听及ConfigrableApplicationContext配置应用上下文。当完成刷新应用的上下文和调用SpringApplicationRunListener#contextPrepared方法后表示SpringBoot应用程序已经启动完成。

onContext配置应用上下文。当完成刷新应用的上下文和调用SpringApplicationRunListener#contextPrepared方法后表示SpringBoot应用程序已经启动完成。


  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot的启动流程可以分为以下几个步骤: 1. 应用主入口:Spring Boot的应用主入口是一个标有@SpringBootApplication注解的类。在启动过程中,它会被作为启动类加载到内存中。 2. 配置形式:Spring Boot提供了多种配置Bean的形式。首先是通过定义Bean的方式,在应用主入口类中使用@Bean注解来定义Bean。其次是通过@Configuration类配置方式,在应用主入口类外创建一个专门用于配置Bean的类,并在该类中使用@Bean注解来定义Bean。还有一种方式是通过Spring XML配置文件进行配置。最后,还可以通过自动配置类来配置Bean,这些自动配置类是Spring Boot内部提供的,会根据配置文件和依赖自动完成一些配置工作。 3. 启动流程:在启动阶段,Spring Boot会依次执行以下步骤: - 加载Spring Boot的核心配置文件和依赖的配置文件。 - 创建并初始化Spring的ApplicationContext容器。 - 执行各个自动配置类,完成自动配置工作。 - 执行应用主入口类中的初始化方法,并启动Spring Boot应用。 4. Bean定义加载顺序:在Spring Boot启动过程中,Bean的加载顺序非常重要。如果在主线程加载Bean的同时,有异步线程进行Dubbo调用或加载Bean,可能会导致死锁。为了避免这种情况,应该保证只有一个线程在进行Spring加载Bean的操作。可以在Spring启动完成后再进行异步初始化操作,或者使用Spring的事件机制,在订阅ApplicationStartedEvent事件后再执行异步初始化操作。 综上所述,Spring Boot的启动流程包括应用主入口、配置形式、启动流程和Bean定义加载顺序。在启动过程中,需要注意Bean的加载顺序,以避免死锁情况的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值