Spring Boot的初始化过程

从spring boot 启动过程看apollo的初始化过程( 二) 之前一篇文章《从apollo的初始化看spring boot 1.5.3启动过程( 一)》 说到而apollo的初始化逻辑便放在这里面,本文就继续从此展开 Spring从3.1版本开始增加了ConfigurableEnvironment和PropertySource: ConfigurableEnvironment Spring的ApplicationContext会包含一个Environme... 阅读详情

Spring Boot的初始化过程

Spring Boot是开发微服务的不二利器。它遵从Convention over Configuration原则,看上去非常简约,但实际底下却做了很多工作。本文从Spring Boot应用程序的初始化过程入手,讲解一下其实现细节。
一般Spring Boot的应用都是从main函数开始,调用SpringApplication.run函数。

SpringApplication.run(SomeApp.class, args);

这是一个静态函数,实际上它构造了一个SpringApplicaiton的实例,并调用另外一个run方法,如下所示:

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    return new SpringApplication(sources).run(args);
}

public SpringApplication(Object... sources) {
    // 一系列的初始化
    initialize(sources);
}
private void initialize(Object[] sources) {
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    // 判断是否为Web应用, 依据是此时是否已加载Servlet或ConfigurableWebApplicationContext类
    this.webEnvironment = deduceWebEnvironment();
    // 设置初始化对象,后期在prepareContext时调用
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    // 设置应用监听器,注意与后面的应用运行情况监听器区别
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // 获取当前应用的主类,及带有入口函数main的类
    this.mainApplicationClass = deduceMainApplicationClass();
}


public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();   ----- (1)
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args); ----- (2)
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);   ----- (3)
        ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);    ----- (4)
        // 打印spring标志
        Banner printedBanner = printBanner(environment);
        // 创建应用上下文对象
        context = createApplicationContext();
        analyzers = new FailureAnalyzers(context);   ----- (5)
        prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);      ----- (6)
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        listeners.finished(context, null);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
        }
        return context;
    }
    catch (Throwable ex) {
        handleRunFailure(context, listeners, analyzers, ex);
        throw new IllegalStateException(ex);
    }
}

1. StopWatch

StopWatch是Spring Framework的一个辅助类,它的作用是记录曾经执行的一系列任务,并在这些任务结束时统计其运行的时间。StopWatch有一个函数名叫prettyPrint,一听就知道它会做一些漂亮的输出工作,例如:

 -----------------------------------------
    ms     %     Task name
    -----------------------------------------
    02000  020%  initializing
    05000  050%  processing
    03000  030%  finalizing

一般Spring Boot程序启动完成后都会输出整个启动过程花了多长时间,这个任务就是由StopWatch来完成的。

2. SpringApplicationRunListeners

这是一个Spring应用运行情况监听类的集合类。这句话比较拗口,实际上它就是将一些事件监听对象集合在一起的类,这些对象都继承自SpringApplicationRunListener接口。从名字上就可以判断出它们是用于监听应用的运行情况的。具体监听哪些事件,查看一下接口的定义就一目了然了。

public interface SpringApplicationRunListener {
    // 应用开始启动
    void starting();
    // 环境变量准备完毕
    void environmentPrepared(ConfigurableEnvironment environment);
    // 上下文对象准备完毕
    void contextPrepared(ConfigurableApplicationContext context);
    // 上下文对象加载完毕
    void contextLoaded(ConfigurableApplicationContext context);
    // 应用启动结束
    void finished(ConfigurableApplicationContext context, Throwable exception);
}

Spring Boot调用getRunListeners(args),从ClassPath中搜寻该接口的实现类,实例化,并将结果保存在这个监听对象集合类里。不过并不是所有实现类都会被实例化,只有在ClassPath中所有“META-INF/spring.factories”文件中声明的实现类才会被实例化。默认情况下,这个接口只在spring-boot-.jar包里的“META-INF/spring.factories”声明,内容如下:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

这个文件里还有很多其他配置。可见,虽然Spring Boot的架构原则是Convenience Over Configuration, 但是并非绝对,仍然还有一些配置。

获取监听器之后,调用listeners.starting( ),即可执行这些监听器的starting方法。

3. ApplicationArguments

这是Spring Boot提供的处理应用参数的接口,同时Spring Boot还提供了一个实现类DefaultApplicationArguments。使用起来非常直白,只要在构造时代入参数args,使用时只要getOptionNames,getOptionValues即可。

4. ConfigurableEnvironment

读取各种环境变量,包括系统环境变量,JVM的属性,以及web servlet容器的属性等等。

5. FailureAnalyzers

失败分析器。这跟ApplicationRunListeners类似,也是根据spring.factories里的配置生成相应的对象。

6. prepareContext

这里主要是对应用的上下文对象进行初始化,应用初始化对象(SpringApplication构造时获取的那些初始化对象,定义在spring.factories里),加载bean等等。

Created with Raphaël 2.1.0StartUserApp RunSpringApplication Runcreate & prepare APP contextrefresh contextcallRunnersEnd
从apollo的初始化看spring boot 1.5.3启动过程( 一) 最早接触springboot,给人第一印象的是两个关键点。 @SpringBootApplication SpringApplication 以及 run() 方法 一、springApplication 实例的初始化 其中,四个关键的步骤已标注在图中,分别解释如下 ① 推断应用的类型:创建的是否为 Servlet 或者 webApplicationContext的一种 ② 使用... 阅读详情

相关推荐

从补码原理到实践:RISC-V中addi指令的符号扩展机制详解

本文深入解析了RISC-V架构中addi指令的符号扩展机制。从补码的数学原理出发,详细阐述了12位立即数在指令编码中如何通过符号位进行扩展,并结合lui指令,揭示了加载任意32位立即数的正确方法与实践陷阱,帮助开发者编写高效可靠的底层代码。

weixin_29161719的博客 139

(粗阅)springboot的初始化顺序

s

小母牛倒立的博客 1725

IEC 62061 总结与适用范围

IEC 62061 是国际电工委员会(IEC)制定的。

cactusDaYe的博客 1083

springboot的初始化启动过程

目录: 构造SpringApplication实例对象 SpringApplication run方法核心逻辑 Environment简介 application配置文件加载过程 创建ApplicationContext ioc容器刷新前prepareContext ioc容器refresh过程(上篇) ioc容器refresh过程(下篇) ioc依赖注入 springboot自动配置机制 aop切面处理过程 springboot事务自动配置 自动配置springboot mvc

FREEDOM 1346

视觉SLAM十四讲--第13讲 实践:设计SLAM系统(最详细的代码调试运行步骤)

最详细的代码调试运行避坑说明,也包含了我自己对代码的理解,如有理解错误的地方,欢迎指正交流。

记录和分享 1万+

Gamit 数据处理,相关的文件配置

一、处理前准备 1、在主文件夹内新建test项目文件,项目内新建brdc、igs和rinex三个文件夹,分别存放广播星历,精密星历几观测值文件,所用的命令分别为sh_get_nav、sh_get_orbits和sh_get_rinex (若文件为.Z,用gunzip命令解压,若仍为d,用命令sh_crx2rnx -f 命令解压为o文件) 2、进入test项目文件夹,链接tables,运行 sh_setup -yr 2015 -apr itrf08_com.apr 3、生成station.info文件。 将t

CodeDoraemon的博客 3375

SpringBoot(一)之初始化

SpringBoot初始化

aoxiaojun的博客 2369

对LSTM中每个batch都初始化隐含层的理解

不知道有没有人和我有一样疑惑 在LSTM相关的代码中,为什么每个batch都会将隐藏层重新初始化, 这样不会把以前训练出来的参数丢掉吗?? 比如 代码来自GitHub 看了一些解释是h与c是状态,不是参数,每个batch中都需要初始化为0,LSTM 中的参数是W,b。 网络中训练的是参数,不是状态。 说真的。。。当时我没怎么看懂。。。 咨询了实验室的师兄后,我有了自己的理解 产生误解的主要原因是我对RNN和LSTM的结构理解不深入,我们通常看到RNN结构图基本都是这样的 ...

Chauncey_Wang的博客 5910

springboot启动流程(一):初始化过程

一、springboot的main函数 一般我们会这么写springboot的启动类 这个类需要注意的是有两点,一个是@SpringBootApplication注解,还有就是run方法。 1、@SpringBootApplication注解 点进注解进入后,看到的情况如下1.1@ComponentScan 是熟悉的包扫描,因为默认是没有配置的,所以spring框架实现会从当前类的包下进行扫码 1.2@EnableAutoConfiguration 借助@...

Dalton2017的博客 1875

RT-DETR改进策略【独家融合改进】| SPD-Conv+PPA 再次提升模型针对小目标的特征提取能力

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。

Limiiiing的博客 1154

【图像去噪】基础知识之加噪 | 给图像加噪的若干种方式,包括加高斯白噪声(AWGN)、泊松-高斯噪声、模拟真实噪声(SIDD、DND)等

本文介绍给干净图像加噪的若干种方式,新手入门必看!。根据noise类型不同,产生不同的Noisy,Noisy一般是模型输入。【图像去噪】基础知识之图像流 | 图像从输入到输出的前世今生,包括类型变化、维度变化、数值变化等。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1100

Spring加载后初始化的9种方式

执行优先级:init-Method >> InitializingBean >> PostConstruct >> SmartInitializingSingleton >> ContextRefreshedEvent >> SpringApplicationRunListener:started >> CommandLineRunner >> SpringApplicationRunListener:ready。

kinbridge的专栏 3356

趋势跟踪策略

/ 绘制K线图的下跌部分,使用绿色标记 stickline(close>=open,high,close,1,1,colorgreen);end // 在图表上绘制当前趋势的图标,如果trend=1或-1 drawicon(trend=1,stopprice,10);end // 绘制K线图的上涨部分,使用红色标记 stickline(close>=open,high,close,1,1,colorred);

2401_84919512的博客 356

02-Spring 容器的初始化与 Spring Boot 启动过程解析

Spring 是企业级开发的核心框架之一,而 Spring Boot 进一步简化了 Spring 应用的开发和部署。了解 Spring 容器的初始化过程以及 Spring Boot 的启动流程,不仅有助于排查异常,还能帮助我们更好地理解 Spring 的核心机制。 本文将通过源码视角,深入解析: - Spring 容器的初始化阶段 - Spring Boot 的启动流程 - 各个关键类和方法的作用

無言的博客 1254

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【Spring Boot 源码学习】深入 ConfigurableEnvironment 的初始化过程

本篇 Huazie 带大家深入了解 ConfigurableEnvironment 的初始化

Huazie 1885

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

(转)Spring Boot启动过程 和 Bean初始化过程中的拓展接口详解

转自: Spring Boot启动过程和 Bean初始化过程中的拓展接口详解_guyue35的博客-优快云博客Spring Boot启动过程和 Bean初始化过程中的拓展接口详解1.背景 Spring的核心思想就是容器,当容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片。Springboot更是封装了Spring,遵循约定大于配置,加上自动装配的机制。很多时候我们只要引用了一个依赖,几乎是零配置就能完成一个功能的装配。 我非常喜欢这种自动装配的机制,所以在自己开发中间件.

PacosonSWJTU的博客 1127

spring boot环境初始化过程

先看一下最简单的spring boot中环境中有些什么东西,首先spring boot的版本是1.5.9 @RequestMapping(value = "/hello") @RestController public class HelloWorld { @Autowired private AbstractEnvironment environment; @Re...

鶸者为何战斗 896

spring-boot初始化过程

spring-boot初始化过程

毅香雪海的博客 239

Spring Boot如何简化Spring应用的初始化和开发过程

综上所述,Spring Boot通过自动化配置、starter依赖、内嵌Web服务器、属性文件配置、命令行工具以及健康检查和监控等功能,显著简化了Spring应用的初始化和开发过程。这使得开发者能够更专注于业务逻辑的实现,提高开发效率和质量。Spring Boot通过多种方式显著简化了Spring应用的初始化和开发过程,让开发者能够更快速、更高效地构建出高质量的应用程序。举一个例子来说明Spring Boot如何简化Spring应用的初始化和开发过程,我们可以考虑一个简单的Spring Web应用的创建。

m0_60521228的博客 2158

Spring Boot启动过程 和 Bean初始化过程中的拓展接口详解

Spring Boot启动过程和 Bean初始化过程中的拓展接口详解 1.背景 Spring的核心思想就是容器,当容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片。Springboot更是封装了Spring,遵循约定大于配置,加上自动装配的机制。很多时候我们只要引用了一个依赖,几乎是零配置就能完成一个功能的装配。 我非常喜欢这种自动装配的机制,所以在自己开发中间件和公共依赖工具的时候也会用到这个特性。让使用者...

我是guyue,guyue就是我O(∩_∩)O 3039

spring Boot关于Bean的集中注入方式,以及初始化过程

1、创建bean的三种方式   使用bean注解直接注入   实现FactoryBean   在其他类中间接创建 1 @Configuration 2 public class MyConfig { 3 4 @Bean 5 @Scope("prototype") 6 public MyBean createBean(){ 7 ...

weixin_30338481的博客 183

mybatis-spring-boot-starter初始化原理及调用过程分析(一)

Springboot启动MapperScan注解处理及mybaits-spring-boot-autoconfigure自动配置容器初始化原理 首先关注MapperScan注解 @SpringBootApplication @Slf4j @MapperScan("com.example.mybatis.mybatisdemo.dao") public class MybatisdemoApplication implements ApplicationRunner { @Autowired

wrz115533的博客 706

@SpringBootApplication :简化 Spring Boot 项目的配置和初始化过程

注解是 Spring Boot 框架的核心特性之一,它极大地简化了 Spring 应用程序的配置和启动过程。通过合理使用该注解及其定制选项,开发者可以创建出高效、稳定且易于维护的 Spring Boot 应用程序。同时,遵循最佳实践和注意事项,能够进一步提高开发效率和代码质量。在未来的开发中,随着 Spring Boot 的不断演进和社区的不断壮大,`

wddblog的博客 1555

源码解析spring boot中websocket endpoint的初始化及启动过程

参考:9.3.17. Create WebSocket Endpoints Using @ServerEndpoint spring boot整合websocket源码解析 org.springframework.web.socket.server.standard.ServerEndpointExporter#registerEndpoints /** * Actually register...

u013905744的专栏 4021
上一篇: 【转帖】计算机体系结构——存储体系
下一篇: 【解决】g++: error trying to exec ‘cc1plus’: execvp
RocWay007
博客等级 码龄24年 37粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值