springboot启动过程(一)
拉步甲(濒危二级)
参考:
https://gitee.com/easyRelax/jdk_web_source_meet_you
前置条件:
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
注释翻译(部分):
引导启动Spring application
- 创建一个适当的ApplicationContext实例(取决于您的类路径)
- 注册一个CommandLinePropertySource,将命令行参数公开为Spring属性
- 刷新应用程序上下文,加载所有单例bean
- 触发任何commandlinerrunner bean
在大多数情况下,静态run(Class, String[])方法可以直接从main方法中调用来引导应用程序。
SpringApplications可以从各种不同的来源读取bean。
- AnnotatedBeanDefinitionReader加载的完全限定类名
- XmlBeanDefinitionReader要加载的XML资源的位置,或者GroovyBeanDefinitionReader要加载的groovy脚本的位置
- 要被ClassPathBeanDefinitionScanner扫描的包的名称
new SpringApplication() 初始化了
- this.resourceLoader 首次启动,这一步null
- this.primarySources
- this.webApplicationType
- this.bootstrapRegistryInitializers
- this.initializers
- this.listeners
- this.mainApplicationClass
run(String... args)
- 创建BootstrapContext && 执行bootstrapRegistryInitializers
- 设置java.awt.headless https://www.jianshu.com/p/7248b3ff5ca7
- 通过main方法参数args,以及SpringApplication.class, String[].class ,从spring.factories加载并通过反射实例化SpringApplicationRunListener的实现类EventPublishingRunListener,并把结果和this.applicationStartup设置到SpringApplicationRunListeners中
listeners.starting(bootstrapContext, this.mainApplicationClass);
- 创建DefaultApplicationStartup,穿了参数spring.boot.application.starting,但没有使用
- 执行this.listeners,之前仅实例化了EventPublishingRunListener,这里执行EventPublishingRunListener.starting,
1)跳转执行 SimpleApplicationEventMulticaster#multicastEvent,有个Executor空的,不知道什么场景下会用到
2)依据ApplicationStartingEvent和eventType加载ApplicationListener的实现类
3)使用map写了缓存,缓存对象CachedListenerRetriever
4)缓存为空,则从this.defaultRetriever.applicationListeners和this.defaultRetriever.applicationListenerBeans过滤符合supportsEvent条件的ApplicationListener的实现类
5)supportsEvent有调用本地方法,不知道做了什么
6)最后加载了LoggingApplicationListener,BackgroundPreinitializer,DelegatingApplicationListener
7)执行上一步加载的listener,查看各自的过滤条件,最后实际执行的只有LoggingApplicationListener
8)执行LoggingApplicationListener#onApplicationEvent,初始化了Slf4JLoggingSystem?并执行了其中的beforeInitialize方法
9)执行DefaultApplicationStartup中的tag方法,什么都没写,return this,返回值也没引用。
10)执行DefaultApplicationStartup中的end方法,end空方法
#springboot##源码阅读##悬赏#