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名称列表
返回上下文。






















上一篇:SpringBoot自动配置原理


下一篇:spring boot SpringApplication.run 执行过程