96SEO 2026-02-19 18:26 23
。

心随星辰#xff0c;徜徉远方#xff0c;岁月静好#xff0c;愿如此刻般绵长。
在黄昏的余晖里梦境渐浓如烟如雾。
心随星辰徜徉远方岁月静好愿如此刻般绵长。
应用程序。
它提供了一种简化的方式来配置和启动应用程序减少了开发者的工作量。
本文将对
{SpringApplication.run(App.class,
中定义了大量的属性这些属性基本上都设置了默认值可供之后的方法使用。
SYSTEM_PROPERTY_JAVA_AWT_HEADLESS
LogFactory.getLog(SpringApplication.class);//
ListApplicationContextInitializer?
ListBootstrapRegistryInitializer
bootstrapRegistryInitializers;//
allowBeanDefinitionOverriding;//
ApplicationContextFactory.DEFAULT;//
中表面上有两个有参构造器。
但是第一个构造器是通过调用第二个构造器实现对象的初始化所以SpringApplication
SpringApplication(ResourceLoader
不为空否则抛出异常Assert.notNull(primarySources,
this.primarySourcesthis.primarySources
LinkedHashSet(Arrays.asList(primarySources));//
Reactivethis.webApplicationType
WebApplicationType.deduceFromClasspath();//
列表中this.bootstrapRegistryInitializers
ArrayList(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));//
实例并设置为初始器setInitializers((Collection)
getSpringFactoriesInstances(ApplicationContextInitializer.class));//
实例并设置为监听器setListeners((Collection)
getSpringFactoriesInstances(ApplicationListener.class));//
this.mainApplicationClassthis.mainApplicationClass
的构造器中这一部分没有给定初始值的属性会在构造器中计算出初始值。
例如resourceLoader、primarySources、webApplicationType、bootstrapRegistryInitializers、mainApplicationClass
现在剩下的方法我们再进行一次划分我们将剩下的方法分为setter、getter
而在这些方法中addBootstrapRegistryInitializer、addInitializers、addListeners、addPrimarySources
退出应用程序并返回退出码。
接收一个应用程序上下文和一个或多个退出码生成器作为参数。
*
检查上下文是否为空Assert.notNull(context,
获取应用程序上下文中所有的退出码生成器CollectionExitCodeGenerator
context.getBeansOfType(ExitCodeGenerator.class).values();//
添加传入的退出码生成器和上下文中的退出码生成器到生成器集合中generators.addAll(exitCodeGenerators);generators.addAll(beans);//
打印异常堆栈信息ex.printStackTrace();//
应用程序并根据上下文中存在的退出码生成器确定合适的退出码。
如果在关闭过程中发生异常也会适当地处理并返回一个退出代码。
SpringApplication(primarySources).run(args);
createBootstrapContext();ConfigurableApplicationContext
属性configureHeadlessProperty();//
获取运行监听器SpringApplicationRunListeners
通知监听器应用程序即将启动listeners.starting(bootstrapContext,
DefaultApplicationArguments(args);//
BeanInfoconfigureIgnoreBeanInfo(environment);//
设置应用程序启动信息context.setApplicationStartup(this.applicationStartup);//
准备应用程序上下文prepareContext(bootstrapContext,
刷新应用程序上下文refreshContext(context);//
在刷新后执行其他操作afterRefresh(context,
Duration.ofNanos(System.nanoTime()
StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(),
通知监听器应用程序已启动listeners.started(context,
处理运行失败情况handleRunFailure(context,
Duration.ofNanos(System.nanoTime()
通知监听器应用程序已准备就绪listeners.ready(context,
处理运行失败情况handleRunFailure(context,
管理各个进程和服务探测所有剩余的硬件挂载文件系统并运行桌面环境。
步骤
综上上面的计算机启动过程太多我们可以进一步总结为以下三个主要阶段引导、启动和运行。
引导阶段在此阶段计算机会执行基本输入/输出系统BIOS或统一可扩展固件接口UEFI等引导加载程序以加载操作系统的引导记录并将操作系统内核加载到内存中。
启动阶段一旦操作系统内核被加载到内存中计算机将开始执行操作系统的初始化过程包括建立内存管理、初始化进程、加载驱动程序等操作。
运行阶段在这个阶段操作系统已经完全加载并且用户界面准备就绪用户可以登录系统并开始使用计算机进行各种任务。
SpringApplicationRunListeners、准备环境
ConfigurableApplicationContext并完成应用容器的初始化工作运行阶段应用容器准备就绪可以使用
就如同计算机启动过程中的内核首先完成内核的加载。
之后通过内核初始化应用容器
ConfigurableApplicationContext类似操作系统。
当操作系统初始化成功最终容器达可运行阶段可供使用。
的引导阶段并没有计算机的引导阶段那么复杂。
这一阶段主要是创建引导容器
ConfigurableApplicationContext。
其次在这一阶段也会启动
SpringApplicationRunListeners以及准备环境
ConfigurableApplicationContext准备应用程序上下文
第一个核心内容创建应用容器其实很好理解。
因为这就是我们真正使用的容器。
我们唯一需要知道的就是应用容器的创建时机是在此处。
应用程序时准备应用程序的上下文。
它的主要步骤包括设置环境、应用初始化器、记录启动信息、注册单例
工厂属性、延迟初始化、添加属性源排序后处理器、加载应用程序源并通知监听器应用程序上下文的准备和加载完成。
这些步骤确保了应用程序上下文的正确配置和准备为应用程序的顺利启动提供了必要的准备工作。
prepareContext(DefaultBootstrapContext
context,ConfigurableEnvironment
将环境对象设置到应用程序上下文中context.setEnvironment(environment);//
对应用程序上下文进行后处理postProcessApplicationContext(context);//
应用初始化器到应用程序上下文中applyInitializers(context);//
通知监听器应用程序上下文已准备好listeners.contextPrepared(context);//
关闭引导上下文bootstrapContext.close(context);//
{logStartupInfo(context.getParent()
null);logStartupProfileInfo(context);}//
工厂ConfigurableListableBeanFactory
springApplicationArgumentsbeanFactory.registerSingleton(springApplicationArguments,
{beanFactory.registerSingleton(springBootBanner,
AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory)
设置是否允许循环引用((AbstractAutowireCapableBeanFactory)
beanFactory).setAllowCircularReferences(this.allowCircularReferences);//
定义覆盖((DefaultListableBeanFactory)
beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}//
{context.addBeanFactoryPostProcessor(new
LazyInitializationBeanFactoryPostProcessor());}//
工厂后处理器context.addBeanFactoryPostProcessor(new
PropertySourceOrderingBeanFactoryPostProcessor(context));//
getAllSources();Assert.notEmpty(sources,
通知监听器应用程序上下文已加载完成listeners.contextLoaded(context);
对象设置到应用程序上下文中以便上下文可以使用这个环境中的配置和属性。
context.setEnvironment(environment);后处理应用程序上下文调用自定义方法对应用程序上下文进行额外的处理。
具体实现取决于开发者的需求这一步一般用于添加额外的配置或修改上下文的某些属性。
postProcessApplicationContext(context);应用初始化器调用所有注册的
applyInitializers(context);通知监听器上下文已准备通知所有
SpringApplicationRunListener应用程序上下文已准备好。
这通常用于在上下文被刷新之前执行一些操作。
listeners.contextPrepared(context);关闭引导上下文关闭引导上下文释放资源。
bootstrapContext.close(context);记录启动信息如果启用了启动信息记录记录启动信息和配置文件信息。
这对于调试和诊断问题很有帮助。
{logStartupInfo(context.getParent()
null);logStartupProfileInfo(context);
ConfigurableListableBeanFactory
beanFactory.registerSingleton(springApplicationArguments,
{beanFactory.registerSingleton(springBootBanner,
AbstractAutowireCapableBeanFactory)
{((AbstractAutowireCapableBeanFactory)
beanFactory).setAllowCircularReferences(this.allowCircularReferences);if
beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}
LazyInitializationBeanFactoryPostProcessor以推迟
{context.addBeanFactoryPostProcessor(new
LazyInitializationBeanFactoryPostProcessor());
PropertySourceOrderingBeanFactoryPostProcessor确保属性源按照预期顺序被处理。
context.addBeanFactoryPostProcessor(new
PropertySourceOrderingBeanFactoryPostProcessor(context));加载应用程序源获取所有应用程序源并加载它们。
确保源不为空否则抛出异常。
SpringApplicationRunListener应用程序上下文已加载完成。
这是最后一步表示上下文已经完全准备好可以启动应用程序了。
listeners.contextLoaded(context);此阶段我们需要了解的是这一阶段是在处理容器准备容器还未开始处理
this.applicationStartup.start(spring.context.refresh);
准备此上下文以进行刷新。
prepareRefresh();//
工厂。
ConfigurableListableBeanFactory
工厂。
prepareBeanFactory(beanFactory);try
工厂进行后处理。
postProcessBeanFactory(beanFactory);StartupStep
this.applicationStartup.start(spring.context.beans.post-process);//
的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);//
处理器。
registerBeanPostProcessors(beanFactory);beanPostProcess.end();//
初始化此上下文的消息源。
initMessageSource();//
初始化此上下文的事件广播器。
initApplicationEventMulticaster();//
lazy-init单例。
finishBeanFactoryInitialization(beanFactory);//
最后一步发布相应事件。
finishRefresh();}catch
销毁已创建的单例以避免资源悬挂。
destroyBeans();//
的元数据...resetCommonCaches();contextRefresh.end();
}记录启动步骤记录上下文刷新过程的启动步骤用于性能监控和排错。
this.applicationStartup.start(spring.context.refresh);准备刷新这个方法用于准备上下文刷新包括设置环境、属性源和早期事件发布等。
ConfigurableListableBeanFactory
prepareBeanFactory(beanFactory);后处理
postProcessBeanFactory(beanFactory);调用
BeanFactoryPostProcessor用于修改应用上下文的内部
invokeBeanFactoryPostProcessors(beanFactory);注册
registerBeanPostProcessors(beanFactory);初始化消息源初始化应用上下文中的消息源用于国际化消息处理。
initMessageSource();初始化事件广播器初始化事件广播器用于发布应用上下文中的事件。
initApplicationEventMulticaster();特定子类的刷新操作留给子类实现的钩子方法允许在刷新上下文时添加一些特定的逻辑。
onRefresh();注册监听器查找并注册所有的事件监听器。
registerListeners();实例化所有剩余的单例实例化所有非延迟初始化的单例
finishBeanFactoryInitialization(beanFactory);完成刷新最后一步主要是清理缓存和发布事件标志着上下文刷新完成。
finishRefresh();刷新应用程序上下文的逻辑是比较复杂的。
我们可以看到在
方法中只有刷新的流程但是没有具体的操作具体的操作都在方法里面。
obtainFreshBeanFactory()postProcessBeanFactory()invokeBeanFactoryPostProcessors()registerBeanPostProcessors()
invokeBeanFactoryPostProcessors()
BeanDefinitionRegistryPostProcessor以便开发者可以在
BeanDefinitionRegistryPostProcessorBean
运行阶段其实没什么特别需要讨论的。
这一阶段容器已准备就绪Bean
已加载完成。
剩下的只是计算一下整个容器启动所花费的时间然后通知监听器容器已处于就绪状态。
容器启动流程然后在此基础上进行总结的。
这种方式有个非常大的弊端由于每个人总结的思路不同会导致结果不一致从而形成了多种说法。
懂的人自然懂初学者或者想要深入理解
容器生命周期的人会自然而然的产生疑惑不知道究竟哪个版本更为准确。
在应用启动之初被调用。
此时除非必要不应该执行任何需要配置环境或上下文的操作。
**
的引导上下文用于存储和共享跨多个阶段的数据。
*/default
starting(ConfigurableBootstrapContext
当环境准备完毕时被调用。
在这个阶段可以对环境进行进一步的自定义。
**
environmentPrepared(ConfigurableBootstrapContext
bootstrapContext,ConfigurableEnvironment
contextPrepared(ConfigurableApplicationContext
contextLoaded(ConfigurableApplicationContext
started(ConfigurableApplicationContext
started(ConfigurableApplicationContext
ready(ConfigurableApplicationContext
running(ConfigurableApplicationContext
当应用启动过程中发生错误时被调用。
此时可以记录错误信息或进行其他的错误处理操作。
**
failed(ConfigurableApplicationContext
的逻辑。
我们仔细回顾一下源代码就会发现SpringApplication
中相应的方法标志当前的处理阶段同时会执行一些该阶段的处理逻辑。
failed但这个是容器异常的情况可能会在任意阶段发生所以不应该属于生命周期的某个指定阶段。
started(ConfigurableApplicationContext
started(ConfigurableApplicationContext
ready(ConfigurableApplicationContext
running(ConfigurableApplicationContext
容器的生命周期其实并没有官方的明确定义官方也可能会对一些细节进行重新定义。
但是我们可以采用官方在
方法被调用时。
作用这个阶段最早发生可以用于执行一些初始化操作比如设置启动参数、记录日志等。
Environment包括系统属性、环境变量、配置文件等准备好之后。
作用此阶段可以用来修改或添加环境属性或者做一些依赖于环境配置的初始化操作。
之前。
作用可以对应用上下文进行进一步配置设置一些全局属性或注册额外的组件。
时间点在应用完全准备好并能够响应请求时。
作用此阶段标志着应用已经完全启动并准备就绪可以处理实际的业务请求。
BeanDefinitionRegistryPostProcessorBean
开发者只需要发布生命周期对应的事件就可以实现在生命周期的指定阶段实现特定功能。
ApplicationEnvironmentPreparedEvent
ApplicationContextInitializedEvent
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback