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

Cogito-v1-preview-llama-3B惊艳表现:128k长文本中精准定位跨段落逻辑矛盾

Cogito-v1-preview-llama-3B惊艳表现:128k长文本中精准定位跨段落逻辑矛盾 你有没有遇到过这样的情况?读完一篇很长的报告或文章,总觉得哪里不对劲,前后说法好像有点矛盾,但又说不清楚具体是哪两句话冲突了。或者,在审核一份复杂的合同时,需要逐字逐句地比对不同条款之间是否存在隐藏的逻辑漏洞。 过去,这种工作只能靠人工完成,不仅耗时耗力,还容易因为疲劳而遗漏关键问题。但现在,有一个专门为此而生的AI模型出现了——Cogito-v1-preview-llama-3B。 这个仅有30亿参数的小模型,却拥有一个令人惊叹的“超能力”:它能在长达128k字符的文本中,像侦探一样精准地找出跨越多个段落的逻辑矛盾。今天,我就带你深入了解这个模型的强大之处,看看它是如何工作的,以及你能用它来做什么。 1. 认识Cogito:不只是聊天,更擅长“思考” 你可能用过很多AI聊天模型,它们能回答问题、写文章、写代码,表现都很不错。但Cogito系列模型有些不一样——它们被设计成“会思考的AI”。 1.1 什么是混合推理模型? 简单来说,Cogito模型有两种工作模式: 标

By Ne0inhk
【工创赛2025-智能物流搬运塔吊方案开源(2分15秒)】西安理工大学工程训练中心

【工创赛2025-智能物流搬运塔吊方案开源(2分15秒)】西安理工大学工程训练中心

一、前言        时光荏苒,岁月如梭。三年的本科竞赛生涯随着工训赛的结束告一段落。竞赛路途中,受到了诸多大佬的帮助和鼓励。为了将这份开源精神传递下去,本团队全体成员一致决定无偿开源本项目机械设计图纸、PCB设计、电控代码、视觉代码及镜像文件、参赛文档以及其他有关设计资料。        请注意,本项目开源文件完全免费,内容遵循CC 4.0 BY-NC-SA版权协议,转载请给出适当的署名,不可用作商业用途,严禁倒卖,若广大网友发现以上行为,请第一时间与我取得联系。        在此,由衷感谢西安理工大学工程训练中心的各位老师对我们竞赛项目的悉心指导与鼎力支持。         这里放一张二代小车同堂的照片作为纪念 二、关于开源项目        运行视频:[开源]2025工训赛智能物流搬运,初赛第八,2分26秒_哔哩哔哩_bilibili        本项目参与了2025年中国大学生工程实践与创新能力大赛全国总决赛,初赛成绩仅1个二环,其余均为一环,总时间2分26秒。决赛由于准备不足以及现场不可预料的因素,成绩不算理想,最后总成绩为全国特等奖。

By Ne0inhk
实操变现|我靠Python爬知乎热榜+AI生成日报,无脑月入8000+,完整项目开源(保姆级教程,新手可复刻)

实操变现|我靠Python爬知乎热榜+AI生成日报,无脑月入8000+,完整项目开源(保姆级教程,新手可复刻)

一、开篇碎语:Python副业的真谛,从来不是「技术多牛」,而是「落地变现」 作为一名深耕Python开发6年的工程师,我见过太多人陷入一个误区:学了Python爬虫、学了数据分析、学了AI,却不知道怎么变现,每天对着一堆练手项目自我感动,最后感叹「Python学了没用」。 我想说的是:Python能赚钱,而且能轻松赚副业的钱,只是你找错了方向,也找错了项目。 真正能落地变现的Python副业,从来都不是那些「高大上的分布式爬虫」「复杂的机器学习项目」,而是轻量、稳定、可自动化、有刚需的小项目。这类项目技术门槛低,新手能快速上手,不用投入太多时间,甚至能做到「自动化运行,躺赚收益」。 而我今天要分享的这个「Python爬知乎热榜+AI生成精选日报」项目,就是这样一个「完美副业项目」。 这个项目我从去年开始实操,至今稳定月入8000+,最高的时候月入12000,全程不用上班摸鱼,不用手动码字,不用费心找选题:Python自动化爬取知乎热榜的所有优质内容,自动筛选去水,再用AI一键生成排版精美的「

By Ne0inhk