Spring boot启动原理及相关组件

Spring boot启动原理及相关组件

优质博文:IT-BLOG-CN

一、Spring Boot应用启动

一个Spring Boot应用的启动通常如下:

@SpringBootApplication@Slf4jpublicclassApplicationMain{ publicstaticvoidmain(String[] args){ ConfigurableApplicationContext ctx =SpringApplication.run(ApplicationMain.class, args);}}

执行如上代码,Spring Boot程序启动成功。事实上启动Spring Boot应用离不开SpringApplication。
所以,我们跟随SpringApplication的脚步,开始从源码角度分析Spring Boot的初始化过程。

btw,可参看例子一节,我对Spring Boot启动的拓展点都做了demo,可参照下面源码分析进行理解。

文档有一句话说了SpringApplication做了什么(目的):

Create an appropriate ApplicationContext instance (depending on your classpath)Register a CommandLinePropertySourcetoexpose command line arguments as Spring properties Refresh the application context, loading all singleton beans Trigger any CommandLineRunner beans 

二、SpringApplication构造函数

启动代码先创建SpringApplication示例,在执行run方法:

publicstaticConfigurableApplicationContextrun(Class<?>[] primarySources,String[] args){ returnnewSpringApplication(primarySources).run(args);}

如下是SpringApplication的构造函数代码分析。

this.resourceLoader = resourceLoader;Assert.notNull(primarySources,"PrimarySources must not be null");this.primarySources =newLinkedHashSet<>(Arrays.asList(primarySources));//通过Classloader探测不同web应用核心类是否存在,进而设置web应用类型this.webApplicationType =WebApplicationType.deduceFromClasspath();//找出所有spring.factories中声明的ApplicationContextInitializer并设置,//ApplicationContextInitializer定义了回调接口,在refresh()前初始化调用(即在prepareContext的applyInitializers方法中调用)setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));//找出所有spring.factories中声明的ApplicationListener(细节往后再叙),ApplicationListener继承了//java.util.EventListener,实现了类似观察者模式的形式,通过实现ApplicationListener、SmartApplicationListener,能够监听Spring上下文的refresh、Prepared等事件或者是自定义事件setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class));//找出主启动类(有趣的是,是通过new一个runtime异常然后在异常栈里面找出来的)this.mainApplicationClass =deduceMainApplicationClass();

在构造期间,主要做了:
1、判定应用类型,为后面创建不同类型的spring context做准备。
2、初始化ApplicationContextInitializer和ApplicationListener。
3、找出启动类。

三、run()源码解析

介绍run()方法前,先说说贯穿run方法的ApplicationRunListener,它有助于理解整个run()的运行周期。
写在这里:Spring Application事件机制

run()方法分析如下:

//java.awt.headless,是J2SE的一种模式,用于在缺失显示屏、鼠标或者键盘时的系统配置。configureHeadlessProperty();//将spring.factories中的SpringApplicationRunListener接口实现类拖出来,塞到SpringApplicationRunListeners(一个集合)中,统一批量执行SpringApplicationRunListeners listeners =getRunListeners(args);//触发runlistener的starting listeners.starting();try{ ApplicationArguments applicationArguments =newDefaultApplicationArguments( args);ConfigurableEnvironment environment =prepareEnvironment(listeners, applicationArguments);//spring.beaninfo.ignore如果没有设置值,则把它设为true,具体情况具体设置,//如果没用的话,把它设为true可以ignore掉classloader对于不存在的BeanInfo的扫描,提高性能。configureIgnoreBeanInfo(environment);//banner打印。自定义banner挺好玩的Banner printedBanner =printBanner(environment);//根据webApplicationType(一开始推断的应用类型)去新建applicationContext context =createApplicationContext();//获取SpringBootExceptionReporter,回调接口类,提供启动时的异常报告 exceptionReporters =getSpringFactoriesInstances(SpringBootExceptionReporter.class,newClass[]{ ConfigurableApplicationContext.class}, context);//下面会说prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);//do nothingafterRefresh(context, applicationArguments);//计时停止 stopWatch.stop();//打日志if(this.logStartupInfo){ newStartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}//启动 listeners.started(context);//找出context的ApplicationRunner和CommandLineRunner,用AnnotationAwareOrderComparator排序,并执行callRunners(context, applicationArguments);

下面再分别说说两个方法(prepareEnvironment、refreshContext)的代码。

四、prepareEnvironment

privateConfigurableEnvironmentprepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments){ // Create and configure the environmentConfigurableEnvironment environment =getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());//发布environment prepared事件 listeners.environmentPrepared(

Read more

【AI大模型前沿】通义万相Wan2.2:阿里270亿参数巨兽开源,消费级显卡就能跑,免费平替Sora上线

【AI大模型前沿】通义万相Wan2.2:阿里270亿参数巨兽开源,消费级显卡就能跑,免费平替Sora上线

系列篇章💥 No.文章1【AI大模型前沿】深度剖析瑞智病理大模型 RuiPath:如何革新癌症病理诊断技术2【AI大模型前沿】清华大学 CLAMP-3:多模态技术引领音乐检索新潮流3【AI大模型前沿】浙大携手阿里推出HealthGPT:医学视觉语言大模型助力智能医疗新突破4【AI大模型前沿】阿里 QwQ-32B:320 亿参数推理大模型,性能比肩 DeepSeek-R1,免费开源5【AI大模型前沿】TRELLIS:微软、清华、中科大联合推出的高质量3D生成模型6【AI大模型前沿】Migician:清华、北大、华科联手打造的多图像定位大模型,一键解决安防监控与自动驾驶难题7【AI大模型前沿】DeepSeek-V3-0324:AI 模型的全面升级与技术突破8【AI大模型前沿】BioMedGPT-R1:清华联合水木分子打造的多模态生物医药大模型,开启智能研发新纪元9【AI大模型前沿】DiffRhythm:西北工业大学打造的10秒铸就完整歌曲的AI歌曲生成模型10【AI大模型前沿】R1-Omni:阿里开源全模态情感识别与强化学习的创新结合11【AI大模型前沿】Qwen2.5-Omni:

By Ne0inhk

【研发规范】Git 提交(commit)、CodeReview规范

本文将分为三个部分: 1. 为什么需要提交规范? 2. 提交规范详解(核心内容) 3. 与 Code Review 流程的结合 1. 为什么需要提交规范? 在 Code Review 前,如果提交的代码杂乱无章,审查者会非常痛苦: * 理解成本高:审查者需要花费大量时间猜测这个提交到底做了什么和为什么这么做。 * 范围不明确:一个提交里混杂了多个功能的修改,难以聚焦审查。 * 历史追溯困难:混乱的提交信息使得日后排查问题、生成变更日志(Changelog)变得几乎不可能。 良好的提交规范旨在解决这些问题,它的核心目标是:让每一次提交都是一个逻辑独立、意图明确、易于理解的故事单元。 2. 提交规范详解 一份优秀的提交(Commit)主要由两部分组成: 1. 提交信息 2. 提交内容(代码变更集) A. 提交信息规范 提交信息是写给未来维护者(包括你自己) 的说明文档。一个常见的规范格式是:

By Ne0inhk
【Linux工具】git

【Linux工具】git

文章目录 * Git 概述 * 主要功能 * 使用场景 * 资源链接 * 使用和下载git * 总结 Git 概述 Git是一个流行的分布式版本控制系统,主要用于跟踪计算机文件的变化,尤其是在软件开发中。它允许多个开发者协同工作,并管理项目的版本历史。 主要功能 1. 版本跟踪 记录文件的每次更改,用户可以随时回溯到先前的版本。 2. 分支管理 允许开发者创建独立的工作线,便于新特性的开发和实验。 3. 合并功能 轻松合并不同分支的更改,处理冲突并保持代码整洁。 4. 分布式操作 每个开发者都有完整的代码库副本,允许离线工作并提高效率。 使用场景 * 软件开发 最常见的用途,管理源代码的版本控制。 * 文档管理 跟踪文档修改历史,尤其是在团队协作中。 资源链接 * Git官方文档 * Atlassian的Git指南 使用和下载git 如果在你的Linux系统上没有下载git那么我们可以使用下面命令进行下载 sudo yum install -y git 这里我

By Ne0inhk
开源力量:GitCode+昇腾NPU 部署Mistral-7B-Instruct-v0.2模型的技术探索与经验总结

开源力量:GitCode+昇腾NPU 部署Mistral-7B-Instruct-v0.2模型的技术探索与经验总结

开源力量:GitCode+昇腾NPU 部署Mistral-7B-Instruct-v0.2模型的技术探索与经验总结 目录 开源力量:GitCode+昇腾NPU 部署Mistral-7B-Instruct-v0.2模型的技术探索与经验总结 摘要 一、技术背景 1.1 昇腾NPU 1.2 GitCode平台 1.3 vLLM Ascend 二、环境准备 2.1 创建GitCode Notebook 2.2 配置Hugging Face镜像 三、部署方案一:原生部署(transformers + torch_npu) 3.1 安装依赖 3.2 下载模型 3.3 推理代码 3.

By Ne0inhk