spring boot SpringApplication.run 执行过程
SpringApplication static run(Object source, String... args)
->new SpringApplication(sources).run(args);
->SpringApplication.initialize(Object[] sources);
->deduceWebEnvironment(),检查 {"javax.servlet.Servlet","org.springframework.web.context.ConfigurableWebApplicationContext"} 是否存在,如果存在则是web环境,否则不是web环境
->ClassUtils.isPresent(String className, ClassLoader classLoader);//check class, default classLoader is null
->ClassUtils.forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError;//load class
->原子类型map,公共类缓存检查name是否存在,存在则返回,否则检查是否是数组,如果是是数组则取数组内层名称递归调用forName,否则使用类加载器加载该类
->通过getSpringFactoriesInstances初始化 ApplicationContextInitializer 接口的实例
->SpringFactoriesLoader.loadFactoryNames(type, classLoader));根据类型加载,读取FACTORIES_RESOURCE_LOCATION="META-INF/spring.factories"相关资源,名为"META-INF/spring.factories"有很多,
扫描相关包,一直找到含有ApplicationContextInitializer的包,最后在
jar:file:/D:/Users/jwlv/.m2/repository/org/springframework/boot/spring-boot/1.5.16.RELEASE/spring-boot-1.5.16.RELEASE.jar!/META-INF/spring.factories中找到如下属性
0 = {Hashtable$Entry@1897} "org.springframework.boot.diagnostics.FailureAnalyzer" -> "org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer"
1 = {Hashtable$Entry@1898} "org.springframework.boot.env.EnvironmentPostProcessor" -> "org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor"
2 = {Hashtable$Entry@1899} "org.springframework.boot.SpringApplicationRunListener" -> "org.springframework.boot.context.event.EventPublishingRunListener"
3 = {Hashtable$Entry@1900} "org.springframework.context.ApplicationContextInitializer" -> "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,org.springframework.boot.context.ContextIdApplicationContextInitializer,org.springframework.boot.context.config.DelegatingApplicationContextInitializer,org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer"
4 = {Hashtable$Entry@1901} "org.springframework.boot.env.PropertySourceLoader" -> "org.springframework.boot.env.PropertiesPropertySourceLoader,org.springframework.boot.env.YamlPropertySourceLoader"
5 = {Hashtable$Entry@1902} "org.springframework.context.ApplicationListener" -> "org.springframework.boot.ClearCachesApplicationListener,org.springframework.boot.builder.ParentContextCloserApplicationListener,org.springframework.boot.context.FileEncodingApplicationListener,org.springframework.boot.context.config.AnsiOutputApplicationListener,org.springframework.boot.context.config.ConfigFileApplicationListener,org.springframework.boot.context.config.DelegatingApplicationListener,org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,org.springframework.boot.logging.ClasspathLoggingApplicationListener,org.springframework.boot.logging.LoggingApplicationListener"
6 = {Hashtable$Entry@1903} "org.springframework.boot.diagnostics.FailureAnalysisReporter" -> "org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter"
加载3 = {Hashtable$Entry@1900} "org.springframework.context.ApplicationContextInitializer"中的四个类
在jar:file:/D:/Users/jwlv/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.16.RELEASE/spring-boot-autoconfigure-1.5.16.RELEASE.jar!/META-INF/spring.factories
0 = {Hashtable$Entry@2121} "org.springframework.boot.autoconfigure.AutoConfigurationImportFilter" -> "org.springframework.boot.autoconfigure.condition.OnClassCondition"
1 = {Hashtable$Entry@2122} "org.springframework.boot.diagnostics.FailureAnalyzer" -> "org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer"
2 = {Hashtable$Entry@2123} "org.springframework.boot.autoconfigure.AutoConfigurationImportListener" -> "org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener"
3 = {Hashtable$Entry@2124} "org.springframework.context.ApplicationContextInitializer" -> "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer"
4 = {Hashtable$Entry@2125} "org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider" -> "org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider"
5 = {Hashtable$Entry@2126} "org.springframework.context.ApplicationListener" -> "org.springframework.boot.autoconfigure.BackgroundPreinitializer"
6 = {Hashtable$Entry@2127} "org.springframework.boot.autoconfigure.EnableAutoConfiguration" -> "org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,org.springfra
加载3 = {Hashtable$Entry@2124} "org.springframework.context.ApplicationContextInitializer" 中的两个类
最终返回下面6个类名,需要被初始化
0 = "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer"
1 = "org.springframework.boot.context.ContextIdApplicationContextInitializer"
2 = "org.springframework.boot.context.config.DelegatingApplicationContextInitializer"
3 = "org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer"
4 = "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer"
5 = "org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer"
->createSpringFactoriesInstances根据以上返回的类名集合进行实例化,存在SpringApplication.initializers中
->初始化 ApplicationListener 接口的实例,过程与实例化initializer类似,最后会实例化一下listener,存在SpringApplication.listeners中
0 = "org.springframework.boot.ClearCachesApplicationListener"
1 = "org.springframework.boot.builder.ParentContextCloserApplicationListener"
2 = "org.springframework.boot.context.FileEncodingApplicationListener"
3 = "org.springframework.boot.context.config.AnsiOutputApplicationListener"
4 = "org.springframework.boot.context.config.ConfigFileApplicationListener"
5 = "org.springframework.boot.context.config.DelegatingApplicationListener"
6 = "org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener"
7 = "org.springframework.boot.logging.ClasspathLoggingApplicationListener"
8 = "org.springframework.boot.logging.LoggingApplicationListener"
9 = "org.springframework.boot.autoconfigure.BackgroundPreinitializer"
->deduceMainApplicationClass()推断main class,通过new RuntimeException().getStackTrace()获取栈帧列表,寻找main方法。
->SpringApplication.run(String... args)
->通过getSpringFactoriesInstances初始化 SpringApplicationRunListener 接口的实例(org.springframework.boot.context.event.EventPublishingRunListener)并启动,
初始化环境信息new StandardServletEnvironment(),
处理banner,就是启动画面,
实例化上下文ConfigurableApplicationContext,根据web环境根据org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext实例化,
否则根据org.springframework.context.annotation.AnnotationConfigApplicationContext实例化,
初始化FailureAnalyzers,用于分析,
根据前面初始化的各项配置,准备上线文信息prepareContext(ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner),其中context.setEnvironment(environment)初始化ApplicationContext,MessageSource,LifecycleProcessor,ApplicationEventMulticaster,
ResourcePatternResolver,BeanFactoryPostProcessor,applicationListeners,ConfigurableListableBeanFactory
applyInitializers(context)使用上下文中的初始化器,
context.getBeanFactory().registerSingleton("springApplicationArguments",applicationArguments)加载spring特殊的单例bean,
实例化BeanDefinitionLoader,含有sources,annotatedReader,xmlReader,scanner,groovyReader属性,用于读取各类配置,加载各类跑配置,
加载用于初始化的SpringBootServletInitializer的子类上的各项配置。
根据准备好的参数刷新上下文refreshContext(context),初始化一些底层和公用的上下文中的bean, 调用AbstractApplicationContext中onRefresh()方法,然后通过createEmbeddedServletContainer()创建容器,
其中会使用tomcatEmbeddedServletContainerFactory。
初始化bean的时候,会有一个mergedBean的概念,比如,首先有一个Bean A,初始化A的时候,会检查A有没有parent,然后A和parent会合并成mergedBean b,然后b会递归之前的流程直到没有依赖,这个过程中会初始化是否单例等属性,
如果一个bean a的包含在一个非单例的bean b中,那a就不是单例。
最终,在onRefresh()中会启动tomcat。
然后finishBeanFactoryInitialization(beanFactory)方法会初始化其他非lazy-init的bean,首先会遍历所以注册的bean名称列表
返回上下文。
spring boot SpringApplication.run 执行过程的更多相关文章
- Spring Boot SpringApplication启动类(二)
目录 前言 1.起源 2.SpringApplication 运行阶段 2.1 SpringApplicationRunListeners 结构 2.1.1 SpringApplicationRunL ...
- Spring Boot SpringApplication启动类(一)
目录 目录 前言 1.起源 2.SpringApplication 准备阶段 2.1.推断 Web 应用类型 2.2.加载应用上下文初始器 ApplicationContextInitializer ...
- Spring Boot程序的执行流程
Spring Boot的执行流程如下图所示:(图片来源于网络) 上图为SpringBoot启动结构图,我们发现启动流程主要分为三个部分,第一部分进行SpringApplication的初始化模块,配置 ...
- 在Spring Boot启动后执行指定代码
在开发时有时候需要在整个应用开始运行时执行一些特定代码,比如初始化环境,准备测试数据等等. 在Spring中可以通过ApplicationListener来实现相关的功能,不过在配合Spring Bo ...
- Spring Boot 之异步执行方法
前言: 最近的时候遇到一个需求,就是当服务器接到请求并不需要任务执行完成才返回结果,可以立即返回结果,让任务异步的去执行.开始考虑是直接启一个新的线程去执行任务或者把任务提交到一个线程池去执行,这两种 ...
- Spring Boot Async异步执行
异步调用就是不用等待结果的返回就执行后面的逻辑,同步调用则需要等带结果再执行后面的逻辑. 通常我们使用异步操作都会去创建一个线程执行一段逻辑,然后把这个线程丢到线程池中去执行,代码如下: Execut ...
- Spring Boot 定时+多线程执行
Spring Boot 定时任务有多种实现方式,我在一个微型项目中通过注解方式执行定时任务. 具体执行的任务,通过多线程方式执行,单线程执行需要1小时的任务,多线程下5分钟就完成了. 执行效率提升10 ...
- spring Boot打可执行的jar包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- spring boot 启动后执行初始化方法
http://blog.csdn.net/catoop/article/details/50501710 1.创建实现接口 CommandLineRunner 的类 package org.sprin ...
- Spring Boot启动时执行初始化操作三种方法分享
@PostConstruct对于注入到Spring容器中的类,在其成员函数前添加@PostConstruct注解,则在执行Spring beans初始化时,就会执行该函数.但由于该函数执行时,其他Sp ...
随机推荐
- 互联网监控直播-LiveGBS分发出RTMP、HLS、FLV、RTSP视频流说明介绍
背景需求 需求比视频流协议更重要,你想要什么,什么可以满足你的需求,这个很大程度上是需求在前,选择使用什么视频流是比较靠后的. 目前Live系列互联网直播服务将全线支持HLS.RTMP.HTTP-FL ...
- 4. gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器
原文地址: gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器 gazebo仿真环境中添加robotiq 2f 140的gripper_controll ...
- 漏洞解析--CSRF
漏洞原理 核心 CSRF(跨站请求伪造)漏洞的核心在于:浏览器会在跨站请求中自动附带用户的 Cookie 等身份凭证,导致攻击者可以诱导用户在已登录的情况下对目标网站发起恶意请求. 原理详解 用户登录 ...
- prometheus + consul 服务注册+报警 最佳实践
一. 说明 本文主要将prometheus和consul 结合起来使用,通过conusl 注册服务至prometheus,实现服务统一注册,统一报警管理等. 整个架构思路consul+consul_e ...
- 流程控制 for switch range break goto
func forCase() { for i := 0; i < 10; i++ { if i == 5 { continue } fmt.Println("位置1 执行 for 语句 ...
- go 变量作用域
package _case import "errors" // SumCase 值传递 func SumCase(a, b int) (sum int, err error) { ...
- ruoyi-vue列表显示关联
之前我们讲解了如何使用ruoyi去自动生成代码,自动做成菜单,增删改查的功能都有了,现在我们来做点改进,比如这里需要显示正确的姓名. 而且同时我们还想让这个自增长编号这一列不再显示,那么我们需要打开这 ...
- Lec 10 线程
Lec 10 线程 目录 Lec 10 线程 License 1 为什么需要线程 1.1 简单方法:进程+调度 1.2 Fork 方法存在局限性 1.3 如何使得进程跨核心运行 1.4 线程:更加轻量 ...
- 【OpenGL ES】在Windows上手撕一个mini版的渲染框架
1 前言 1.1 开发该框架的动机 OpenGL ES 是一个渲染指令接口集合,每渲染一帧图像都是一系列渲染指令的排列组合.常用的渲染指令约有 70 个,记住这些渲染指令及其排列组合方式,是一件痛 ...
- P10698 [SNCPC2024] 最大流
P10698 [SNCPC2024] 最大流 题意 给一个 \(n\) 个点 \(m\) 条边的 DAG,起点为 \(1\),终点不定,容量全为 \(1\).再给定一个常数 \(k\).设从 \(1\ ...