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 ...
随机推荐
- 实现领域驱动设计——什么是DDD?
一.写在前面 今天的软件相对之前的软件,需求越来越复杂,变化越来越快.软件架构不断的在演进,一方面是为了适应新的需求,一方面也在寻找软件简单化解决方案,通过架构的规范是的软件更容易维护,逻辑更清晰.所 ...
- SpringBoot使用AOP优雅的实现系统操作日志的持久化!
基于AOP+Spring实现操作日志记录:从设计到落地全指南 在日常开发中,操作日志是系统不可或缺的一部分--它用于追溯用户行为.排查问题.审计安全操作.但如果在每个业务方法中硬编码日志逻辑,会导致代 ...
- 联通贝尔光猫TTL破解维护账户
试过不少用普通用户登录后,直接访问定义地址下载配置文件的方法,目前没找到有用的.因此决定TTL破解.1一.购买TTL工具(推荐FT232RL),链接TX-RX/RX-TX/GND-GND,因光猫主板没 ...
- uni-app项目支付宝端Input不受控
前情 最近又接手一个全新多端项目,包括抖音/快手/微信/支付宝,其中就有支付宝端,需要实现一个SKU选择,同时需要控制选择的商品数量,如下图 坑位 既然是选择商品数量,那就不能让它出现小于等于0的数, ...
- 从零开始: c#纯代码实现完整Json解析器的全过程及注释与自定义格式的支持实现
大家好!我们要深入探讨一个非常常用的技术:JSON反序列化.别小看这个技术,它可是现代编程中不可或缺的一部.JSON解析不仅仅是简单的数据转换,它还涉及到复杂的词法分析和文法解析.这些技术是编译器设计 ...
- iis搭建discuz7.2 的曲折经历 y以及各种报错的处理
环境windows server 2008 R2 mysql 5.1.73 iis6 php 5.6 安装PHP 解压PHP,我给的路径是C:\Users\Administrator\De ...
- Lec2 交互学习策略和度量(MAB问题)
Chapter 2 MAB问题 参考:动手学强化学习,建议读者去看看原文 2.1 简介 智能体与环境交互学习,试错型学习. 多臂lh机(后简称MAB)问题,是一种简化的强化学习问题. 不存在状态信息, ...
- ORA-600 16703故障,客户找人恢复数据库,数据库被进一步恶意破坏—ORA-00704 ORA-00922---惜分飞
有朋友找到我,数据库报ORA-600 16703错误,这个本来是一个比较常见的破坏故障(警告:互联网中有oracle介质被注入恶意程序导致-ORA-600 16703数据库启动报错如下: 修复tab$ ...
- 为什么不该用 Double 表示金额及解决方案
众所周知,double 和 float 这些浮点数其实是不精确的. 比如 0.1 + 0.2 并不等于 0.3,而是等于 0.30000000000000004--这也一度成为程序员圈子里的经典梗.所 ...
- Redis之key的过期策略
1.前言 redis作为一种非关系性数据库,常用来做缓存,不妨来了解下其key的过期策略. 过期字典:reids将所有过期的键值都放在一个字典中,而这个字典就叫做过期字典. 键空间:服务器中的每个数据 ...