简历写了解熟悉SpringBoot?请说一说 SpringBoot 的启动流程

阿里P9大牛带你在简历上写精通Spring与Boot高级功能 蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力、培训、出国、大公司的经历,还有很多很好的朋友。但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,可惜我错过了,我用这五年时间和很多程序员一样在困惑和迷茫中找不到出路!路其实一直都在那里,只是我们看不到而已!以前我一直被公司和技术牵着走,并不是自己在选择技术,而是不自觉地被推到了这个位置上。想想有多少人对于自己将来要从事的职业和技术类型进行过深入思考和比较呢?当我跳出编码后,我开始思考和程序及程序员职业生涯相关 阅读详情

springBoot启动流程分析:

springBoot启动流程主要分两步:

  1. new SpringApplication()应用
  2. 运行 SpringApplication()对象

进入run方法:

    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

new SpringApplication()应用

进入new SpringApplication(primarySources)

    public SpringApplication(Class<?>... primarySources) {
        //传入一个null
        this((ResourceLoader)null, primarySources);
    }

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = new HashSet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        //初始化一个空的resourceLoader
        this.resourceLoader = resourceLoader;
        //断言primaySources 是否为空
        Assert.notNull(primarySources, "PrimarySources must not be null");
        //初始化主要加载资源类,并去重
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        //判断web应用类型 NONE(非web项目),SERVLET(web项目),REACTIVE(响应式web项目);
        this.webApplicationType = WebApplicationType.deduceFromClasspath();

        //设置应用上下文 初始化器
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
        //设置监听器
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

        //推断主入口类
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }

关键点:设置应用上下文初始化器、设置监听器

其两者做的事情是一样的,我们跟一下 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); 源码。

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
        return this.getSpringFactoriesInstances(type, new Class[0]);
    }

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        //载入所有的ApplicationContextInitializer的类全限定名
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        //使用反射将所有的ApplicationContextInitializer实例化
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

关键点:载入所有的ApplicationContextInitializer的类全限定名

    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        //取出所有 factoryTypeName(这里指ApplicationContextInitializer)所有类的全限定名
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }
    /**
    * 解析出所有 META-INF/spring.factories 文件的属性返回
    **/
    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        //先从缓存取
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                //取出所有 META-INF/spring.factories 文件路径
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    //转为 Properties 对象
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();
                    
                    //解析 Properties 
                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

再看一下META-INF/spring.factories文件:

spring是在所有你加载的 jar 包中找到需要的 ApplicationContextInitializer 进行动态配置,只要你用到了特定的 maven 包,初始化时就会找到这个包下的 META-INF/spring.factories 中需要的类进行实例化bean,你就可以用了,不需要任何配置。

运行 SpringApplication()对象

    public ConfigurableApplicationContext run(String... args) {
        //开启启动计时器,项目启动完会打印执行时间出来
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();

        //获取SpringApplicationRunListener并启动监听器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //环境变量的加载  环境变量包括system environment、classpath environment和用户自己加的application.properties
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);

            //启动后console的打印出来的一堆配置信息   
            Banner printedBanner = this.printBanner(environment);

            //ApplicationContext实例化
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);


            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

创建applicationContext又分为几步:createApplicationContext、prepareContext、refreshContext。实例化applicationContext会根据在之前我们说的webEnvironment这个属性判断是使用webContext类AnnotationConfigEmbeddedWebApplicationContext还是普通context类AnnotationConfigApplicationContext(在这里我们使用的是webContext为例)然后通过反射进行实例化。applicationContext实例化完了会进入prepareContext流程,这个prepareContext方法会加载之前准备好的environment进入context中,然后如果有beanNameGenerator和resourceLoader那么提前创建bean加载进applicationContext,但是一般这两个都是空的,所以直接进入applyInitializers方法,将之前实例化的所有initializers进行初始化,所有的bean就是在这里进行bean的扫描和加载的因这次讲的是启动过程,所以不再细讲。最后是refreshContext,这个就和spring的bean加载过程一致了,bean的注入、beanFactory、postProcessBeanFactory等等,详情可以去看看spring bean的生命周期 。最后把创建好的applicationContext设置进入listener,prepareContext过程就结束了。(此段为引用)

总结:

1、创建SpringApplication实例,判定环境,是web环境还是普通环境。加载所有需要用到的Initializers和Listeners,这里使用约定大于配置的理念揭开了自动配置的面纱。
2、创建一个ApplicationContext,设置装配context。最终将装配好的context作为属性设置进SpringApplicationRunListeners。

参考博客:

spring boot启动流程图:https://www.pianshen.com/article/6036196723/

https://www.jb51.net/article/124286.htm

SpringBoot启动流程 本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。 一、SpringBoot启动流程图 二、SpringBoot启动入口 @EnableScheduling @EnableAsync @SpringBootApplication @EnableAspectJAutoProxy @ComponentScan(basePackages = { "cn.gov.zcy.demand", "cn.gov.zcy. 阅读详情

相关推荐

SpringBoot-简历样例

SpringBoot快速入门,一个最简单的,可运行的SpringBoot-web项目。详细介绍:http://blog.youkuaiyun.com/torrytang/article/details/75442448

阿里P9大神教你在简历上写精通Spring与Boot高级功能

本文将带大家全面剖析Spring Framework核心特征及新增功能,助大家轻松掌握Java企业级应用程序开发;深入介绍 Spring Boot高级功能,助大家将微服务快速部署到云端! 本文将带领大家能够在简历上写上精通Spring:JavaWeb开发与SpringBoot高级功能,相信大家也能够端正自己的态度,不断地提升自己的技术深度和广度,让自己变得更加地有价值!! 也希望本文能够帮助到大家的学习!加油!努力成就更好的自己! 目录 主要内容 第1章向Spring Framework 5.

m0_64435718的博客 3923

SAP ABAP实战:手把手教你用BAPI_BILLINGDOC_CREATEMULTIPLE批量开票(附完整代码与避坑指南)

本文详细解析了SAP ABAP中BAPI_BILLINGDOC_CREATEMULTIPLE批量开票的全流程,包括参数配置、事务控制、错误处理及性能优化。通过实战案例和完整代码示例,帮助开发者高效处理大批量发票生成任务,避免常见陷阱,提升开发效率。

weixin_34101914的博客 265

阿里大大师亲自总结,让你可以在简历上写精通SpringBoot

Spring相信大家都用过,那一堆的配置,用起来就好比:你要吃饭,饭是熟的,但是你还要自己(配置)加油盐酱醋,还得搅拌均匀,然后才能吃...... 但是无奈,你的简历上还是得写“精通Spring Boot”。。。那总得大体说得上SpringBoot是个啥东西吧! 学习会了Spring Boot之后,你总得还有一个举一反三的效果,哎说了这么多,不就是为了简历上那一句:精通Spring Boot吗? 总结了两份SpringBoot的学习PDF,免费分享出来,希望大家可以在自己的简历上加上这句“精通Spri

m0_50180963的博客 2506

工业数据采集实战:用open62541库读写PLC的OPC UA节点(避坑指南)

本文详细介绍了如何使用open62541库实现工业PLC的OPC UA节点数据采集,涵盖环境搭建、节点读写优化及生产环境故障排查。通过订阅模式和多节点读写技术,显著提升数据采集效率与稳定性,适用于智能制造和工业物联网场景。

weixin_30598225的博客 398

DIY玩家必备:用SSS1623芯片打造高性价比USB麦克风(附完整电路图)

本文详细介绍了如何利用SSS1623芯片DIY高性价比USB麦克风,包括元件选型、电路设计、PCB布局及调试技巧。通过完整的电路参考设计和实用建议,帮助电子爱好者打造专业级录音设备,实现免驱动即插即用功能。

weixin_29166013的博客 236

简历例句

简介 通用 有良好的代码风格,注重代码质量,通过学习 XXX,XXX 等多个开源项目的架构与源码,确保代码具备健壮性与扩展性。 具备良好的代码编程习惯及文档编写能力,参与 XXX,XXX 项目的核心部分代码编写,重构和维护。能进行技术攻关,突破关键技术瓶颈。 负责根据公司业务及目标引进人才、培养新人、规划团队人员、并建立完善的绩效考核制度有效留住人才,提高工作效率。 带领 10 人团队完成分布式系统的难点分析与架构设计工作,承担 XXX 等核心功能代码编写,开发与维护系统核心模块。使用 XXX 等

wuadmin的博客 1625

RGB接口电容触摸屏驱动(二)接口与时序说明

RGB接口电容触摸屏驱动(二)接口与时序说明

杰克拉力船长个人博客 4915

Springboot和Spring的区别?看完你就明白了

从一道面试题说起 面试的时候经常会被问到,spring和springboot的区别。或者SpringMVC和Springboot的区别。其实这样的问法就不是特别合适。因为spring、springboot、springmvc他们三个在spring体系中就不在同一个维度。 看一下spring的全部项目 spring家族有很多项目,springboot、spring framework、spring cloud等。 我们常用的也就是,springboot、springcloud、springse

qq3164069700的博客 8846

手把手教你用OpenRouter免费模型:从DeepSeek V3.1到Llama 3.3的实战指南

本文详细介绍了如何利用OpenRouter平台免费接入DeepSeek V3.1、Llama 3.3等53个AI模型,提供从账号注册到实战应用的完整指南。通过文本摘要、客服对话生成和代码生成等具体案例,帮助开发者高效利用免费模型资源,提升AI应用开发效率。

weixin_29258297的博客 3546

【ComfyUI】FluxKontext 身形调优与体态增强

AI身形调优与体态增强解决方案 该工作流通过Flux系列模型实现人物体态的智能化增强,主要特点包括: 采用UNet主体模型+双文本编码器+身形增强LoRA的架构组合 通过ReferenceLatent保持原始姿态的同时强化胸腰臀比例 完整工作流包含图像加载、文本编码、潜空间映射等8个核心节点 支持自动化的前后效果对比展示 应用优势: 保持人物自然姿态的前提下实现局部强化 支持通过Prompt精确控制增强方向 适用于摄影后期、角色美化等创作场景 输出效果稳定且风格统一 使用方

Mr数据杨 1294

SpringBoot启动流程总结

一直很好奇SpringBoot这么一个大怪物,启动的时候做了哪些事情,然后看了很多老师讲的教学视频,然后自己想好好整理一下,做下学习笔记下次也方便自己阅读 1、首先从main方法开始看 public static void main(String[] args) { //代码很简单SpringApplication.run(); SpringApplication.run(Cons...

mnicsm的博客 6万+

YOLOv11改进 | 缝合CCFM轻量检测模型实现高精度跨尺度特征融合【附参考代码】

YOLOv11作为一代优秀的端到端目标检测模型,已经在速度和精度之间取得了较好的平衡。但其默认的Neck结构(通常为FPN + PAN)在处理小目标与多尺度信息时,仍存在信息流冗余、跨尺度特征融合不充分等问题。 本文提出一种轻量化的跨尺度跨通道融合模块(CCFM, Cross-scale and Cross-channel Fusion Module),以替代或增强YOLOv11中的Neck部分,有效提升特征表达能力和检测性能,尤其是在小目标和复杂场景下取得显著涨点。

一键难忘的博客 1412

SPRINGBOOT启动流程及其原理

Spring Boot、Spring MVC 和 Spring 有什么区别? 分别描述各自的特征: Spring框架就像一个家族,有众多衍生产品例如boot、security、jpa等等;但他们的基础都是Spring 的ioc和 aop,ioc提供了依赖注入的容器,aop解决了面向切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能。 Spring MV...

u014352080的专栏 3万+

Redis下载安装与配置(windows)

一、Redis下载 二、Redis安装 三、启动Redis临时服务并测试连接(可跳过) 四、Redis配置

欢迎订阅我的“JAVA全栈开发笔记(全)”专栏,价格优惠,仅需19.9元。 7万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SpringBoot系列之【启动流程详解】

文章目录前言一、SpringBoot特点二、SpringBoot启动类入口1.注解:@SpringBootApplication@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan2.main方法SpringApplication#run实例化SpringApplication对象SpringApplication.run(java.lang.String...)三、SpringBoot启动事件EventPublishingRunLis

qq_21609191的博客 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

SpringBoot 启动流程

方法来启动 Spring Boot 应用程序。该方法接受两个参数,第一个参数是启动类的类对象,第二个参数是主方法的参数。方法中做了一系列操作来完成项目启动所需的初始化Spring容器、启动内置tomcat、启动应用程序以及通知监听者等步骤。总的来说,Spring Boot的启动过程是一个复杂的流程,从启动类的Main方法中调用。启动类必须使用 @SpringBootApplication 注解标记该类。方法开始,然后在SpringApplication对象的。方法来执行项目启动的后续操作。

qq_33807380的博客 9554

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

9千字长文带你了解SpringBoot启动过程--史上最详细 SpringBoot启动流程-图文并茂

来自面试官发自内审深处的灵魂拷问:“说一下springboot的启动流程”; 一脸懵逼的面试者:“它简化了spring的配置,主要是因为有自动装配的功能,并且可以直接启动,因为它内嵌了tomcat容器”; 面试官:“嗯, 没错,这是 它的一些概念,你还没回答我的问题,它是怎么启动的,启懂时都经过了哪些东西?”; 一脸懵逼的面试者:“额~~~不知道额····,我用的很熟练,但是不知道它里面做了哪些事情!”; 面试官:“了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路.

weixin_44947701的博客 5万+

总结:Springboot启动流程

一、总结 1、关于SpringApplication SpringBoot的启动主要是通过实例化SpringApplication来启动的。 2、实例化SpringApplication时做了什么? SpringApplication的构造方法做了几件事情: 推断WebApplicationType,主要思想就是在当前的classpath下搜索特定的类 搜索META-INF\spring.factories文件配置的ApplicationContextInitializer的实现类 搜索MET

w2009211777的专栏 1万+

SpringBoot启动原理及相关流程

一、springboot启动原理及相关流程概览 springboot是基于spring的新型的轻量级框架,最厉害的地方当属自动配置。那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 二、springboot的启动类入口 用过springboot的技术人员很显而易见的两者之间的差别就是视觉上很直观的:springboot有自己独立的启动类(独立...

javarrr的博客 5万+

SpringBoot启动流程解析(总结的非常好,很清晰!)

由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图keepRunning方法)。 本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。 总览: 上图为Sprin...

咖啡的博客 3万+

深入了解Springboot框架的启动流程

 Springboot是依赖于spring的,除了拥有spring的全部功能以外,Springboot无需繁琐的xml配置(约定大于配置),有application.properties/yml配置文件,还有static静态配置目录,这取决于它自身强大的自动装配功能;​ 并且自身已嵌入Tomcat、Jetty等web容器,集成了springmvc,使得springboot可以直接运行,不需要额外的容器。 依赖于强大的@EnableAutoConfiguration注解,通过SpringFactoriesLo

weixin_50055999的博客 1161

一文搞懂SpringBoot启动流程及自动配置

SpringBoot启动流程。## 标题 1、启动SpringBoot启动类SpringbootdemoApplication中的main方法。 2、调用SpringApplication.run(SpringbootdemoApplication.class, args),该方法是一个静态方法。 public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return

qq_44530691的博客 1万+

SpringBoot启动流程及其原理

SPRINGBOOT启动流程及其原理 Spring Boot、Spring MVC 和 Spring 有什么区别? 一 springboot启动原理及相关流程概览 二 springboot的启动类入口 三 单单是SpringBootApplication接口用到了这些注解   1)@Configuration注解   2)@ComponentScan注解 3)@EnableAutoConfiguration AutoConfigurationPackage注解: ...

zzk00007的博客 4727

详细了解springBoot 启动流程及其原理

SPRINGBOOT启动流程及其原理 Spring Boot、Spring MVC 和 Spring 有什么区别? 一 springboot启动原理及相关流程概览 二 springboot的启动类入口 三 单单是SpringBootApplication接口用到了这些注解   1)@Configuration注解   2)@ComponentScan注解 3)@EnableAutoConfiguration AutoConfigurationPackage注解:...

qq_31207917的博客 1334
上一篇: 面试官问SpringBoot的核心注解,你说@SpringBootApplication吗??
程序员楂楂
博客等级 码龄9年 17粉丝 70原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值