文章目录
- 【README】
- 【1】springboot启动过程概述
- 【1.1】new SpringApplication()新建SpringApplication实例
- 【1.2】SpringApplication#run()执行步骤概述(非常重要)
- 【2】SpringApplication#run()-step3-初始化(准备)环境
- 【2.1】SpringApplicationRunListeners#environmentPrepared()环境准备完成
- 【2.1.1】EnvironmentPostProcessorApplicationListener#onApplicationEvent()响应ApplicationEnvironmentPreparedEvent事件
- 【3】SpringApplication#run()-step5-初始化容器
- 【3.1】SpringApplication#applyInitializers(context)应用到初始化器
- 【3.2】EnvironmentPostProcessorApplicationListener#响应ApplicationPreparedEvent事件
- 【4】SpringApplication#run()-step6-刷新容器
- 【4.1】AbstractApplicationContext#prepareRefresh()-刷新容器前的准备工作
- 【4.2】准备bean工厂=DefaultListableBeanFactory
- 【4.3】AbstractApplicationContext#postProcessBeanFactory(beanFactory)-BeanFactory后置处理
- 【4.4】AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory): 触发BeanFactory后置处理器
- 【4.5】this.registerBeanPostProcessors(beanFactory)-注册bean后置处理器
- 【4.6】ServletWebServerApplicationContext#onRefresh(): 执行刷新容器(真正的刷新容器)
- 【4.7】AbstractApplicationContext#registerListeners():注册监听器;
- 【4.8】AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory): 完成BeanFactory初始化
- 【4.9】AbstractApplicationContext#finishRefresh()-完成刷新容器
- 【4.9.1】【初始化生命周期处理器】 处理器=DefaultLifecycleProcessor
- 【4.9.2】【DefaultLifecycleProcessor#onRefresh();】生命周期处理器-执行刷新
- 【4.9.3】发布容器已刷新事件ContextRefreshedEvent
- 【5】调用SpringApplication#callRunners()-调用Runner运行器#run方法
【README】
1)springboot作用:springboot扮演了脚手架的作用;
- 脚手架定义(来自百度+维基百科):是为了保证各施工过程顺利进行而搭设的工作平台,供施工人员在墙壁等高处施工,提供施工效率。 简单理解:springboot作为java软件开发脚手架,可以提高开发效率 ;
- springboot如何扮演脚手架? springboot提供了属性加载,自动配置,集成第三方jar功能,即无需开发人员逐个编码实现依赖的组件,仅需设置属性适配springboot配置功能,以提高快速开发的目的 ;
2)springboot中的prepare,字面翻译为准备,但本文翻译为初始化;原因如下 :
【EventPublishingRunListener】事件发布运行监听器 (SpringApplicationRunListener的子类)
- contextPrepared()翻译为容器准备完成,但发布的事件是容器初始化完成事件ApplicationContextInitializedEvent,用的是Initialized-初始化,所以本文也用初始化翻译prepare ,更加符合语义;
public void contextPrepared(ConfigurableApplicationContext context) {this.multicastInitialEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));}
【1】springboot启动过程概述
1)springboot启动main函数所在类定义
@SpringBootApplication
public class FirstApplication {public static void main(String[] args) {SpringApplication.run(FirstApplication.class, args);}
}
【SpringApplication】
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);}
可以查到,SpringApplication.run()静态方法分2步运行,包括new SpringApplication() ,执行SpringApplication实例方法run() ;
【@SpringBootApplication】注解定义
// 被@Configuration标注
@SpringBootConfiguration// 启用自动配置,把所有符合自动配置条件的bean定义加载到spring容器
@EnableAutoConfiguration // 扫描@SpringBootApplication标注的类所在包及子包下的被@Component直接标注或间接标注(如@Configuration)的类,把Component类作为bean注册到spring容器,把Configuration类中被@Bean标注的方法作为bean定义注册到spring容器并实例化
@ComponentScan( excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter( type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}
【1.1】new SpringApplication()新建SpringApplication实例
【SpringApplication】
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath(); // SERVLET// 以下3个方法从 META-INF/spring.factories读取对应类作为key的全限定类名,并实例化this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}
1)上述代码有3行代码特别重要,如下。
this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
2)这3行代码都调用getSpringFactoriesInstances()方法从所有jar包中META-INF/spring.factories读取对应类型的全限定类名,通过setter赋值给SpringApplication对应属性。
- 第1行:读取BootstrapRegistryInitializer类型的全限定类名(包括子类或实现类)并实例化;表示引导启动注册初始化器;
- 第2行:读取ApplicationContextInitializer类型的全限定类名(包括子类或实现类)并实例化;表示应用容器初始化器;
- 第3行:读取ApplicationListener类型的全限定类名(包括子类或实现类)并实例化; 表示应用监听器;
3)META-INF/spring.factories 在 spring-boot制品库,spring-boot-autoconfig制品库存在(当然,在其他制品库jar可能也存在,本文仅贴出2个制品库jar);定义如下:
【spring-boot】制品库中的META-INF/spring.factories
# Application Context Initializers 应用容器初始化器列表
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer# Application Listeners 应用监听器列表
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.DelegatingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener
【spring-boot-autoconfig】制品库中的META-INF/spring.factories
# ApplicationContext Initializers 应用容器初始化器列表
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener# Application Listeners 应用监听器列表
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
【1.2】SpringApplication#run()执行步骤概述(非常重要)
【SpringApplication】run() 方法
public ConfigurableApplicationContext run(String... args) {Startup startup = SpringApplication.Startup.create();if (this.registerShutdownHook) {shutdownHook.enableShutdownHookAddition();}// 1 创建启动类容器 DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();ConfigurableApplicationContext context = null;this.configureHeadlessProperty();// 2 获取 SpringApplicationRunListeners,从 srping.factories 读取SpringApplicationRunListeners listeners = this.getRunListeners(args);// 发布事件 listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 3 创建并初始化环境 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner = this.printBanner(environment);// 4 创建容器 context = this.createApplicationContext();context.setApplicationStartup(this.applicationStartup);// 5 初始化容器 this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 6 刷新容器, 读取BeanDefinition并执行具体的bean实例化this.refreshContext(context);// 7 容器刷新后逻辑,保护方法,由子类实现 this.afterRefresh(context, applicationArguments);startup.started();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), startup);}// 8 SpringApplicationRunListeners 发布已启动事件 listeners.started(context, startup.timeTakenToStarted());// 9 调用运行器 this.callRunners(context, applicationArguments);} catch (Throwable var10) {throw this.handleRunFailure(context, var10, listeners);}try {if (context.isRunning()) {// 10 SpringApplicationRunListeners 发布就绪事件 listeners.ready(context, startup.ready());}return context;} catch (Throwable var9) {throw this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);}}
1)执行步骤:
- step1:创建默认引导启动容器,class=DefaultBootstrapContext;
- step2:从META-INF/spring.factories读取类型为SpringApplicationRunListener-spring应用运行监听器的属性,只有1个监听器,即EventPublishingRunListener-事件发布运行监听器;将其封装到SpringApplicationRunListeners;
- 执行SpringApplicationRunListeners监听器列表的starting方法;广播事件,通知订阅者应用开始启动;
- step3:调用SpringApplication#prepareEnvironment()准备环境, class=ApplicationServletEnvironment ; 参见章节【2】 ;
- step4:调用SpringApplication#createApplicationContext() 创建应用容器,容器class=AnnotationConfigServletWebServerApplicationContext ;
- 从从META-INF/spring.factories读取类型为ApplicationContextFactory-应用容器工厂的属性(获取工厂全限定类名ServletWebServerApplicationContextFactory),然后调用其ServletWebServerApplicationContextFactory#create()方法创建AnnotationConfigServletWebServerApplicationContext 容器;
- step5:调用SpringApplication#prepareContext() 准备容器; 参见章节【3】 ;
- step6:调用SpringApplication#refreshContext() 刷新容器; 参见章节【4】;
- step7:调用SpringApplication#afterRefresh() 执行容器刷新后逻辑; 默认无(SpringApplication默认没有业务逻辑); 【子类可以实现】
- step8:调用SpringApplicationRunListeners监听器的started()方法,发布ApplicationStartedEvent事件,通知订阅者应用启动完成;
- step9:调用SpringApplication#callRunners() ; 调用Runner运行器bean的run方法 ; 参见章节【5】;
- step10:调用SpringApplicationRunListeners监听器的ready()方法,发布ApplicationReadyEvent事件(应用就绪事件);
2)springboot整体启动流程图,如下:
【2】SpringApplication#run()-step3-初始化(准备)环境
【SpringApplication#prepareEnvironment()】 run方法step3-初始化环境:调用SpringApplication#prepareEnvironment()
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// 获取或创建环境 ConfigurableEnvironment environment = this.getOrCreateEnvironment(); this.configureEnvironment(environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach(environment);listeners.environmentPrepared(bootstrapContext, environment);DefaultPropertiesPropertySource.moveToEnd(environment);Assert.state(!environment.containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties.");this.bindToSpringApplication(environment);if (!this.isCustomEnvironment) {EnvironmentConverter environmentConverter = new EnvironmentConverter(this.getClassLoader());environment = environmentConverter.convertEnvironmentIfNecessary(environment, this.deduceEnvironmentClass());}ConfigurationPropertySources.attach(environment);return environment;
}
1)SpringApplication#prepareEnvironment()准备环境执行步骤:
- step1:调用SpringApplication#getOrCreateEnvironment()获取或创建环境对象environment,class=ApplicationServletEnvironment; 调用ServletWebServerApplicationContextFactory#createEnvironment()方法;
- step2:调用SpringApplication#configureEnvironment()配置环境;
- step3:调用SpringApplicationRunListeners#environmentPrepared(),发布事件,通知订阅者环境准备完成;
- step4:调用DefaultPropertiesPropertySource.moveToEnd(environment),把默认属性移动到末尾;
- step5:调用SpringApplication#bindToSpringApplication()把环境绑定到spring应用;
- step6:调用ConfigurationPropertySources.attach(environment):把key=configurationProperties的属性值移动到属性源第一个;
【2.1】SpringApplicationRunListeners#environmentPrepared()环境准备完成
【SpringApplicationRunListeners#environmentPrepared()】
void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {this.doWithListeners("spring.boot.application.environment-prepared", (listener) -> {listener.environmentPrepared(bootstrapContext, environment); // 调用每个监听器的environmentPrepared方法});
}
1)监听器列表:
- 0 = {EventPublishingRunListener@1928} (springboot提供,本文主要关注)
- 1 = {TomSpringAppRunListener01@1929} (自定义,测试用)
2)EventPublishingRunListener#environmentPrepared(), 发布ApplicationEnvironmentPreparedEvent事件;
// EventPublishingRunListenerpublic void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {this.multicastInitialEvent(new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));}private void multicastInitialEvent(ApplicationEvent event) {this.refreshApplicationListeners();this.initialMulticaster.multicastEvent(event);}
3)SimpleApplicationEventMulticaster多播器-multicastEvent()发布事件方法; 显然这个方法是通知订阅了ApplicationEnvironmentPreparedEvent事件,类型=ApplicationEnvironmentPreparedEvent的监听器;监听器列表如下:
- 0 = {EnvironmentPostProcessorApplicationListener@2167} (重点关注)
- 1 = {AnsiOutputApplicationListener@2168}
- 2 = {LoggingApplicationListener@2169}
- 3 = {BackgroundPreinitializer@2170}
- 4 = {DelegatingApplicationListener@2171}
- 5 = {FileEncodingApplicationListener@2172}
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = eventType != null ? eventType : ResolvableType.forInstance(event);Executor executor = this.getTaskExecutor();Iterator var5 = this.getApplicationListeners(event, type).iterator();while(true) {while(var5.hasNext()) {// 调用监听器#environmentPrepared方法}return;}}
【2.1.1】EnvironmentPostProcessorApplicationListener#onApplicationEvent()响应ApplicationEnvironmentPreparedEvent事件
1)事件=ApplicationEnvironmentPreparedEvent, 对应方法为onApplicationEnvironmentPreparedEvent()
// EnvironmentPostProcessorApplicationListener
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment = event.getEnvironment();SpringApplication application = event.getSpringApplication();// 获取环境后置处理器列表EnvironmentPostProcessorsIterator var4 = this.getEnvironmentPostProcessors(application.getResourceLoader(), event.getBootstrapContext()).iterator(); while(var4.hasNext()) {EnvironmentPostProcessor postProcessor = (EnvironmentPostProcessor)var4.next();// 调用每个环境后置处理器的postProcessEnvironment方法 postProcessor.postProcessEnvironment(environment, application); }}
2)环境后置处理器列表(调用环境后置处理器#postProcessEnvironment()方法):
- 0 = {RandomValuePropertySourceEnvironmentPostProcessor@2193}
- 1 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor@2194} (系统环境属性源环境后置处理器,本文重点关注)
- 2 = {CloudFoundryVcapEnvironmentPostProcessor@2195}
- 3 = {SpringApplicationJsonEnvironmentPostProcessor@2196}
- 4 = {ConfigDataEnvironmentPostProcessor@2197}
- 5 = {ReactorEnvironmentPostProcessor@2198}
- 6 = {IntegrationPropertiesEnvironmentPostProcessor@2199}
- 7 = {LogCorrelationEnvironmentPostProcessor@2200}
3)SystemEnvironmentPropertySourceEnvironmentPostProcessor-postProcessEnvironment()方法: 获取systemEnvironment属性源,并做替换;
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {String sourceName = "systemEnvironment";PropertySource<?> propertySource = environment.getPropertySources().get(sourceName);if (propertySource != null) {this.replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());}}
3.1)environment.getPropertySources()得到PropertySourceList(类型为CopyOnWriteArrayList),属性源列表如下:
- 0 = {ConfigurationPropertySourcesPropertySource@2215} ConfigurationPropertySourcesPropertySource {name=‘configurationProperties’} 封装配置属性;
- 1 = {PropertySource$StubPropertySource@2216} StubPropertySource {name=‘servletConfigInitParams’} 封装servlet配置初始化参数;
- 2 = {PropertySource$StubPropertySource@2217} StubPropertySource {name=‘servletContextInitParams’} 封装servlet容器初始化参数;
- 3 = {PropertiesPropertySource@2218} PropertiesPropertySource {name=‘systemProperties’} 封装系统属性(jvm-java虚拟机层面属性) ;
- 4 = {SystemEnvironmentPropertySource@2219} SystemEnvironmentPropertySource {name=‘systemEnvironment’} ; 封装系统环境变量( 操作系统层面属性,作用域范围更大,不仅java进程可以使用,其他进程也可以使用);
- 5 = {RandomValuePropertySource@2220} RandomValuePropertySource {name=‘random’} 封装随机属性;
【3】SpringApplication#run()-step5-初始化容器
【SpringApplication#prepareContext()】SpringApplication#run()-step5-准备容器 , 调用SpringApplication#prepareContext()
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);// 后置处理应用容器 【略过】this.postProcessApplicationContext(context); // 新增AOT生成式初始化器(开启AOT才会执行,本文没有开启,SpringAOT是SpringBoot的新特性,用于将Java字节码编译成本地机器代码,提升启动速度和执行效率【略过】)this.addAotGeneratedInitializerIfNecessary(this.initializers); // 应用初始化器到容器this.applyInitializers(context); // 发布事件,通知订阅者容器准备完成 listeners.contextPrepared(context); // 发布启动容器关闭事件 bootstrapContext.close(context); // 打印日志...// beanFactory=DefaultListableBeanFactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // 注册spring应用参数单例 beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {// 执行;设置允许循环引用autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences); if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {// 执行;设置允许bean定义重写listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}if (this.lazyInitialization) { // 是否懒初始化 context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}if (this.keepAlive) { // 是否保持存活 context.addApplicationListener(new KeepAlive());}// 新增BeanFactory后置处理器context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context)); if (!AotDetector.useGeneratedArtifacts()) {Set<Object> sources = this.getAllSources();Assert.notEmpty(sources, "Sources must not be empty");// 执行;加载启动类class到annotatedReaderthis.load(context, sources.toArray(new Object[0])); }// 发布事件,通知订阅者容器加载完成 listeners.contextLoaded(context);
}
1)步骤列表:
-
step1:应用初始化器到容器;(初始化器类型为ApplicationContextInitializer); 参见章节【3.1】 ;
-
step2:listeners.contextPrepared(context) :遍历所有SpringApplicationRunListener监听器,并执行其contextPrepared()方法;
-
监听器列表如下:
- 0 = {EventPublishingRunListener@3207} (springboot框架提供的SpringApplicationRunListener)
- 1 = {TomSpringAppRunListener01@3208} (自定义 META-INF/spring.factories配置的SpringApplicationRunListener)
-
EventPublishingRunListener#contextPrepared(context): 广播ApplicationContextInitializedEvent事件给订阅者,包括BackgroundPreinitializer,DelegatingApplicationListener; (从step2的执行细节可以看出,先遍历所有SpringApplicationRunListener监听器,调用其contextPrepared方法;然后SpringApplicationRunListener#contextPrepared方法又发布ApplicationContextInitializedEvent事件给订阅该事件的监听器,即总共有2层监听器)
-
-
step3:bootstrapContext.close(context):发布启动容器关闭事件BootstrapContextClosedEvent给订阅该事件的监听器列表;
-
step4: listeners.contextLoaded(context):发布ApplicationPreparedEvent事件给订阅该事件的监听器;监听器列表如下(详情参见【章节3.2】):
- 0 = {EnvironmentPostProcessorApplicationListener@3471} -环境后置处理器应用监听器
- 1 = {LoggingApplicationListener@3473}
- 2 = {BackgroundPreinitializer@3474}
- 3 = {DelegatingApplicationListener@3475}
【3.1】SpringApplication#applyInitializers(context)应用到初始化器
【SpringApplication#applyInitializers()】 初始化器列表(实际上,来自于制品库中的META-INF/spring.factories配置的名为ApplicationContextInitializer的值列表):
- 0 = {DelegatingApplicationContextInitializer@3130}
- 1 = {SharedMetadataReaderFactoryContextInitializer@3145}
- 2 = {ContextIdApplicationContextInitializer@3146}
- 3 = {ConfigurationWarningsApplicationContextInitializer@3147}
- 4 = {RSocketPortInfoApplicationContextInitializer@3148}
- 5 = {ServerPortInfoApplicationContextInitializer@3149}
- 6 = {ConditionEvaluationReportLoggingListener@3150}
protected void applyInitializers(ConfigurableApplicationContext context) {Iterator var2 = this.getInitializers().iterator();while(var2.hasNext()) {ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");initializer.initialize(context);}
}
【3.2】EnvironmentPostProcessorApplicationListener#响应ApplicationPreparedEvent事件
1)EnvironmentPostProcessorApplicationListener-环境后置处理器应用监听器的ApplicationPreparedEvent事件响应
【EnvironmentPostProcessorApplicationListener#onApplicationEvent()】事件响应
public void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent environmentPreparedEvent) {this.onApplicationEnvironmentPreparedEvent(environmentPreparedEvent);}if (event instanceof ApplicationPreparedEvent) {this.onApplicationPreparedEvent(); // 这里}if (event instanceof ApplicationFailedEvent) {this.onApplicationFailedEvent();}}
private void onApplicationPreparedEvent() {this.finish();}
private void finish() {this.deferredLogs.switchOverAll(); // 打印日志【略过】 }
【补充】为什么打印日志,我还要po出来呢?其实是为了展示EventPublishingRunListener-事件发布运行监听器发布事件后,订阅该事件的监听器如何响应的过程, 显然onApplicationEvent是事件响应方法 ;
【4】SpringApplication#run()-step6-刷新容器
1)SpringApplication#refreshContext() 刷新容器
private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {shutdownHook.registerApplicationContext(context);}this.refresh(context);}protected void refresh(ConfigurableApplicationContext applicationContext) {// 实际调用的是spring容器AnnotationConfigServletWebServerApplicationContext的refresh方法 applicationContext.refresh(); }
2)AnnotationConfigServletWebServerApplicationContext父类是ServletWebServerApplicationContext,ServletWebServerApplicationContext父类是AbstractApplicationContext, 所以refresh()刷新容器实际调用的是AbstractApplicationContext#refresh()方法 ;
public final void refresh() throws BeansException, IllegalStateException { // ServletWebServerApplicationContexttry {super.refresh(); // AbstractApplicationContext#refresh()方法} catch (RuntimeException var3) {
// ...}}
【AbstractApplicationContext】抽象应用容器
public void refresh() throws BeansException, IllegalStateException {this.startupShutdownLock.lock(); // 加可重入锁 try {this.startupShutdownThread = Thread.currentThread();StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// 执行刷新容器的准备工作this.prepareRefresh(); // 获取刷新后的bean工厂ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 准备bean工厂=DefaultListableBeanFactorythis.prepareBeanFactory(beanFactory); try {this.postProcessBeanFactory(beanFactory); // 后置处理bean工厂StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");this.invokeBeanFactoryPostProcessors(beanFactory); // 触发bean工厂后置处理器 this.registerBeanPostProcessors(beanFactory);// 注册bean后置处理器 beanPostProcess.end(); this.initMessageSource(); // 初始化消息源 this.initApplicationEventMulticaster();// 初始化应用事件广播器this.onRefresh(); // 刷新容器this.registerListeners(); // 注册监听器 this.finishBeanFactoryInitialization(beanFactory); // 完成bean工厂初始化 this.finishRefresh(); // 完成刷新 } catch (Error | RuntimeException var12) {
// ... throw var12;} finally {contextRefresh.end();}} finally {this.startupShutdownThread = null;this.startupShutdownLock.unlock();}}
3) 具体步骤如下:
- step1:prepareRefresh():执行刷新容器的准备工作; 包括初始化属性源, 转存应用监听器; 参见章节【4.1】
- step2:准备bean工厂=DefaultListableBeanFactory;把Context中的属性注册到bean工厂;参见章节【4.2】
- stpe3: this.postProcessBeanFactory(beanFactory): 后置处理BeanFactory; 参见章节【4.3】
- step4:this.invokeBeanFactoryPostProcessors(beanFactory): 触发BeanFactory后置处理器; 参见章节【4.4】
- step5:this.registerBeanPostProcessors(beanFactory):注册bean后置处理器; 参见章节【4.5】
- step6:this.initMessageSource(): 初始化消息源(注册DelegatingMessageSource消息源到spring容器);
- step7:this.initApplicationEventMulticaster(): 初始化应用事件多播器-SimpleApplicationEventMulticaster, 用于发布ApplicationEvent事件;
- step8: this.onRefresh(): 执行刷新容器(真正的刷新容器) ; 参见章节【4.6】
- step9:this.registerListeners():注册监听器; 参见章节【4.7】
- step10:this.finishBeanFactoryInitialization(beanFactory): 完成BeanFactory初始化(实际上是实例化bean) ; 参见章节【4.8】
- step11: this.finishRefresh():完成刷新容器; 参见章节【4.9】
【4.1】AbstractApplicationContext#prepareRefresh()-刷新容器前的准备工作
【AbstractApplicationContext#prepareRefresh()】刷新容器前的准备工作
protected void prepareRefresh() {this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (this.logger.isDebugEnabled()) {if (this.logger.isTraceEnabled()) {this.logger.trace("Refreshing " + this);} else {this.logger.debug("Refreshing " + this.getDisplayName());}}this.initPropertySources(); // 初始化属性源 this.getEnvironment().validateRequiredProperties();if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners); // 转存应用监听器} else {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}this.earlyApplicationEvents = new LinkedHashSet();}
1)属性源列表:
0 = {ConfigurationPropertySourcesPropertySource@3480} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}" # 配置属性
1 = {PropertySource$StubPropertySource@3481} "StubPropertySource {name='servletConfigInitParams'}" # servlet配置初始属性
2 = {PropertySource$StubPropertySource@3482} "StubPropertySource {name='servletContextInitParams'}" # servlet容器初始属性
3 = {PropertiesPropertySource@3483} "PropertiesPropertySource {name='systemProperties'}" // 系统属性,jvm层面属性
4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@3484} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}" // 环境属性,操作系统层面属性
5 = {RandomValuePropertySource@3485} "RandomValuePropertySource {name='random'}"
2)应用监听器列表:
0 = {RSocketPortInfoApplicationContextInitializer$Listener@3539}
1 = {ServerPortInfoApplicationContextInitializer@3540}
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@3541}
3 = {EnvironmentPostProcessorApplicationListener@2370}
4 = {AnsiOutputApplicationListener@3542}
5 = {LoggingApplicationListener@3543}
6 = {BackgroundPreinitializer@3544}
7 = {DelegatingApplicationListener@3545}
8 = {ParentContextCloserApplicationListener@3546}
9 = {ClearCachesApplicationListener@3547}
10 = {FileEncodingApplicationListener@3548}
11 = {SpringApplicationShutdownHook$ApplicationContextClosedListener@3549}
【4.2】准备bean工厂=DefaultListableBeanFactory
【AbstractApplicationContext#prepareBeanFactory】准备bean工厂
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {beanFactory.setBeanClassLoader(this.getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));if (!NativeDetector.inNativeImage() && beanFactory.containsBean("loadTimeWeaver")) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}if (!beanFactory.containsLocalBean("environment")) {beanFactory.registerSingleton("environment", this.getEnvironment()); // 把Context中的属性注册到bean工厂}if (!beanFactory.containsLocalBean("systemProperties")) {beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean("systemEnvironment")) {beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());}if (!beanFactory.containsLocalBean("applicationStartup")) {beanFactory.registerSingleton("applicationStartup", this.getApplicationStartup());}}
【4.3】AbstractApplicationContext#postProcessBeanFactory(beanFactory)-BeanFactory后置处理
【AbstractApplicationContext#postProcessBeanFactory(beanFactory)】后置处理BeanFactory
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {super.postProcessBeanFactory(beanFactory); // super if (this.basePackages != null && this.basePackages.length > 0) {this.scanner.scan(this.basePackages);}if (!this.annotatedClasses.isEmpty()) {this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));}
}// super=ServletWebServerApplicationContext
【ServletWebServerApplicationContext】
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 注册bean后置处理器 beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class);// 注册web应用作用域this.registerWebApplicationScopes();}
private void registerWebApplicationScopes() {ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(this.getBeanFactory());// 注册web应用作用域WebApplicationContextUtils.registerWebApplicationScopes(this.getBeanFactory()); existingScopes.restore();}
【WebApplicationContextUtils】注册web应用作用域
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {registerWebApplicationScopes(beanFactory, (ServletContext)null);}public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) {beanFactory.registerScope("request", new RequestScope());beanFactory.registerScope("session", new SessionScope());if (sc != null) {ServletContextScope appScope = new ServletContextScope(sc);beanFactory.registerScope("application", appScope);sc.setAttribute(ServletContextScope.class.getName(), appScope);}// 注册bean工厂beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());if (jsfPresent) {WebApplicationContextUtils.FacesDependencyRegistrar.registerFacesDependencies(beanFactory);}}
【4.4】AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory): 触发BeanFactory后置处理器
【AbstractApplicationContext#invokeBeanFactoryPostProcessors()】 触发BeanFactory后置处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 触发bean工厂后置处理器 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors()); if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}
【beanFactory参数】 DefaultListableBeanFactory
【bean工厂后置处理器列表 】
0 = {SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor@3997}
1 = {ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor@3998}
2 = {SpringApplication$PropertySourceOrderingBeanFactoryPostProcessor@3999}
1)PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(beanFactory, beanFactoryPostProcessors)
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {Iterator var2 = postProcessors.iterator();while(var2.hasNext()) {BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");Objects.requireNonNull(postProcessor);StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);// 调用bean工厂后置处理器的postProcessBeanFactory方法 postProcessor.postProcessBeanFactory(beanFactory); postProcessBeanFactory.end();}}
- 遍历每个注册处理器:执行postProcessBeanDefinitionRegistry(registry);
- 如ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry():加载@Configuration配置bean定义到spring容器 ;
- 新增bean后置处理器,如ImportAwareBeanPostProcessor;
- 如PropertySourcesPlaceHolderConfigurer处理器:读取属性(如${propertyName});
- 如DependsOnDatabaseInitializationPostProcessor处理器:加载databaseInitializerBean的定义;
【4.5】this.registerBeanPostProcessors(beanFactory)-注册bean后置处理器
1)注册bean后置处理器,包括
0 = {ConfigurationPropertiesBindingPostProcessor@5295}
1 = {CommonAnnotationBeanPostProcessor@5296}
2 = {AutowiredAnnotationBeanPostProcessor@5297} InfrastructureAdvisorAutoProxyCreator0 = {WebServerFactoryCustomizerBeanPostProcessor@5358}
1 = {ErrorPageRegistrarBeanPostProcessor@5359}
2 = {HealthEndpointConfiguration$HealthEndpointGroupsBeanPostProcessor@5360}
3 = {MeterRegistryPostProcessor@5361}
4 = {ObservationRegistryPostProcessor@5362} 0 = {CommonAnnotationBeanPostProcessor@5296}
1 = {AutowiredAnnotationBeanPostProcessor@5297} ApplicationListenerDetector
【4.6】ServletWebServerApplicationContext#onRefresh(): 执行刷新容器(真正的刷新容器)
【ServletWebServerApplicationContext】onRefresh()刷新容器; 详情参见spring容器启动源码解读 章节3.1 ;
protected void onRefresh() {// super=GenericWebApplicationContextsuper.onRefresh(); try {this.createWebServer(); // 创建web容器} catch (Throwable var2) {throw new ApplicationContextException("Unable to start web server", var2);}}
【ServletWebServerApplicationContext】createWebServer()-创建web容器
private void createWebServer() {WebServer webServer = this.webServer;ServletContext servletContext = this.getServletContext();if (webServer == null && servletContext == null) {StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");// 获取服务器工厂(TomcatServletWebServerFactory)ServletWebServerFactory factory = this.getWebServerFactory(); createWebServer.tag("factory", factory.getClass().toString());// 获取web服务器(TomcatWebServer) this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()}); createWebServer.end();this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer));this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer));} else if (servletContext != null) {try {this.getSelfInitializer().onStartup(servletContext);} catch (ServletException var5) {throw new ApplicationContextException("Cannot initialize servlet context", var5);}}this.initPropertySources(); // 初始化属性源
}
// GenericWebApplicationContext#initPropertySources()-初始化属性源
protected void initPropertySources() {ConfigurableEnvironment env = this.getEnvironment();if (env instanceof ConfigurableWebEnvironment configurableWebEnv) {configurableWebEnv.initPropertySources(this.servletContext, (ServletConfig)null);}}
【4.7】AbstractApplicationContext#registerListeners():注册监听器;
1)AbstractApplicationContext#registerListeners():注册监听器,并与事件多播器(SimpleApplicationEventMulticaster)绑定;
protected void registerListeners() {Iterator var1 = this.getApplicationListeners().iterator();while(var1.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var1.next();this.getApplicationEventMulticaster().addApplicationListener(listener);}String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);String[] var7 = listenerBeanNames;int var3 = listenerBeanNames.length;for(int var4 = 0; var4 < var3; ++var4) {String listenerBeanName = var7[var4];// 绑定监听器到多播器 this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); }Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {Iterator var9 = earlyEventsToProcess.iterator();while(var9.hasNext()) {ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();// 绑定事件到多播器 this.getApplicationEventMulticaster().multicastEvent(earlyEvent); }}}
【this.getApplicationListeners()】监听器列表:
0 = {RSocketPortInfoApplicationContextInitializer$Listener@6573}
1 = {ServerPortInfoApplicationContextInitializer@6574}
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@6575}
3 = {EnvironmentPostProcessorApplicationListener@6576}
4 = {AnsiOutputApplicationListener@6577}
5 = {LoggingApplicationListener@6578}
6 = {BackgroundPreinitializer@6579}
7 = {DelegatingApplicationListener@6580}
8 = {ParentContextCloserApplicationListener@6581}
9 = {ClearCachesApplicationListener@6582}
10 = {FileEncodingApplicationListener@6583}
11 = {SpringApplicationShutdownHook$ApplicationContextClosedListener@6584}
12 = {SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean@6585}
【4.8】AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory): 完成BeanFactory初始化
1)this.finishBeanFactoryInitialization(beanFactory): 完成bean工厂初始化(bean工厂==spring容器);
- 解析环境变量占位符;
- 冻结配置信息;
- 预先实例化单例bean ;
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));}if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver((strVal) -> {return this.getEnvironment().resolvePlaceholders(strVal);});}String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);String[] var3 = weaverAwareNames;int var4 = weaverAwareNames.length;for(int var5 = 0; var5 < var4; ++var5) {String weaverAwareName = var3[var5];try {beanFactory.getBean(weaverAwareName, LoadTimeWeaverAware.class);} catch (BeanNotOfRequiredTypeException var8) {if (this.logger.isDebugEnabled()) {this.logger.debug("Failed to initialize LoadTimeWeaverAware bean '" + weaverAwareName + "' due to unexpected type mismatch: " + var8.getMessage());}}}beanFactory.setTempClassLoader((ClassLoader)null);// 冻结配置信息;beanFactory.freezeConfiguration(); // 预先实例化单例beanbeanFactory.preInstantiateSingletons();
}
【DefaultListableBeanFactory#preInstantiateSingletons()】预先实例化单例bean
预先实例化单例bean,参见:spring bean实例化源码解析-章节3.2
【4.9】AbstractApplicationContext#finishRefresh()-完成刷新容器
【AbstractApplicationContext#finishRefresh()】完成刷新容器
protected void finishRefresh() {// 重置公共缓存this.resetCommonCaches(); // 清空资源缓存 this.clearResourceCaches(); // 初始化生命周期处理器 this.initLifecycleProcessor(); // 生命周期处理器 执行刷新this.getLifecycleProcessor().onRefresh();// 发布容器已刷新事件ContextRefreshedEventthis.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this))); }
【4.9.1】【初始化生命周期处理器】 处理器=DefaultLifecycleProcessor
protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();if (beanFactory.containsLocalBean("lifecycleProcessor")) {this.lifecycleProcessor = (LifecycleProcessor)beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);if (this.logger.isTraceEnabled()) {this.logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}} else {DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);this.lifecycleProcessor = defaultProcessor;beanFactory.registerSingleton("lifecycleProcessor", this.lifecycleProcessor);if (this.logger.isTraceEnabled()) {this.logger.trace("No 'lifecycleProcessor' bean, using [" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}
【4.9.2】【DefaultLifecycleProcessor#onRefresh();】生命周期处理器-执行刷新
public void onRefresh() {// .... if (exitOnRefresh) {Runtime.getRuntime().halt(0);}this.stoppedBeans = null;try {this.startBeans(true); // 开始bean } catch (ApplicationContextException var2) {this.stopBeans();throw var2;}this.running = true;}
// 开启bean
private void startBeans(boolean autoStartupOnly) {Map<String, Lifecycle> lifecycleBeans = this.getLifecycleBeans();Map<Integer, LifecycleGroup> phases = new TreeMap();lifecycleBeans.forEach((beanName, bean) -> {if (!autoStartupOnly || this.isAutoStartupCandidate(beanName, bean)) {int startupPhase = this.getPhase(bean);((LifecycleGroup)phases.computeIfAbsent(startupPhase, (phase) -> {return new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);})).add(beanName, bean);}});if (!phases.isEmpty()) {phases.values().forEach(LifecycleGroup::start);}}
【lifecycleBeans生命周期bean】
"applicationTaskExecutor" -> {ThreadPoolTaskExecutor@6945}
"springBootLoggingLifecycle" -> {LoggingApplicationListener$Lifecycle@6947}
"webServerGracefulShutdown" -> {WebServerGracefulShutdownLifecycle@6949}
"webServerStartStop" -> {WebServerStartStopLifecycle@6951}
【4.9.3】发布容器已刷新事件ContextRefreshedEvent
【AbstractApplicationContext#publishEvent()】发布事件
public void publishEvent(ApplicationEvent event) {this.publishEvent(event, (ResolvableType)null);}
1)订阅了ContextRefreshedEvent事件的监听器如下:
0 = {DelegatingApplicationListener@6667}
1 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@6668}
2 = {ClearCachesApplicationListener@6669}
3 = {SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean@6670}
4 = {ResourceUrlProvider@6671}
【5】调用SpringApplication#callRunners()-调用Runner运行器#run方法
【SpringApplication#callRunners】调用SpringApplication#callRunners()-调用Runner运行器#run方法
private void callRunners(ConfigurableApplicationContext context, ApplicationArguments args) {ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();String[] beanNames = beanFactory.getBeanNamesForType(Runner.class);Map<Runner, String> instancesToBeanNames = new IdentityHashMap();String[] var6 = beanNames;int var7 = beanNames.length;for(int var8 = 0; var8 < var7; ++var8) {String beanName = var6[var8];instancesToBeanNames.put((Runner)beanFactory.getBean(beanName, Runner.class), beanName);}Comparator<Object> comparator = this.getOrderComparator(beanFactory).withSourceProvider(new FactoryAwareOrderSourceProvider(beanFactory, instancesToBeanNames));instancesToBeanNames.keySet().stream().sorted(comparator).forEach((runner) -> {this.callRunner(runner, args); });}
// 调用运行器
private void callRunner(Runner runner, ApplicationArguments args) {if (runner instanceof ApplicationRunner) {this.callRunner(ApplicationRunner.class, runner, (applicationRunner) -> {applicationRunner.run(args);});}if (runner instanceof CommandLineRunner) { // 若为命令行运行器,则执行其run方法this.callRunner(CommandLineRunner.class, runner, (commandLineRunner) -> {commandLineRunner.run(args.getSourceArgs());});}}
