SpringBoot启动流程
2023-01-05 09:34:29 12 举报
登录查看完整内容
springboot
作者其他创作
大纲/内容
创建对象并设置到StandardServletEnvironment对象的变量中ApplicationConversionService
内
1、得到容器初始化器,然后设置到对应的熟悉上2、有三种自定义Initializers的方式
this.postProcessApplicationContext(context);
组合注解
主要就是调用前面11个内置监听器的listener.onApplicationEvent(event);方法
结束
内部很复杂
loadSpringFactories()
SpringApplication对象创建时,到META-INF/spring.factories中加载到的ApplicationContextInitializer列表,并依次调用其initialize方法
执行监听器listeners.starting();
getOrCreateEnvironment();
if (\"main\".equals(stackTraceElement.getMethodName())) {
1、@SpringBootConfiguration2、@EnableAutoConfiguration3、@ComponentScan(excludeFilters = { ...classes = AutoConfigurationExcludeFilter.class) })
deduceMainApplicationClass()
最终顺序
打印图标,可以自定义
暂且就从第一个启动方法入手把,入口应该是这里
WebApplicationType.deduceFromClasspath();
getSpringFactoriesInstances(ApplicationContextInitializer.class));一个通过spring.factories实现SPI模式分析
在EventPublishingRunListener构造函数初始化的时候这个监听器里面还包含一个简单的多播器new SimpleApplicationEventMulticaster();会把前面初始化的监听器注册到这个里面,后面循环调用
applyInitializers(context);
2-1@AutoConfigurationPackage2-2@Import(AutoConfigurationImportSelector.class)
2--->>分析
configureEnvironment();
获取环境变量里面这个参数的值spring.profiles.active
listeners.environmentPrepared(environment);
排序完的顺序
@ComponentScan加载时机和AutoConfigurationExcludeFilter源码解读
3--->>分析
2-1---->分析
查找并设置配置文件信息
将 defaultProperties、commandLine默认文件就是环境变量什么的,命令行,一般在jar启动的时候用的多,我们测试run启动的时候args一般不用参数,如果传参,就是会在这个地方解析
判断是什么类型,创建对应的容器对象并实例化AnnotationConfigServletWebServerApplicationContext
得到所有内置和自定义的监听器SpringApplicationRunListener接口的实现类
printBanner(environment);
就是增加一个对象文件,怎么用不知道todo
调用另一个有参构造函数
stopWatch.start();开始计时
listeners.contextPrepared(context);
createApplicationContext();
2-2---->分析
处理一些bean
通过事件发布器广播了一个事件ApplicationContextInitializedEvent,广播的流程跟之前的几个事件比如ApplicationStartingEvent是完全一致的,就不细看了,最后接收到该事件的监听者一共有两个,但是都没有做实际的处理,我们后续也可以再拉出来看一下,其实跟之前的事件分析流程完全一致的
configureHeadlessProperty();
环境准备
内部逻辑
context.setEnvironment(environment);
run方法内部
这段代码作用主要是将enviroment中以spring.main开头的配置的属性都赋到这个SpringApplication对象里
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
推断主启动类并实例化返回
doGetActiveProfiles()
1、SpringApplication对象中有没有自定义的BeanNameGenerator,有的话就注册到容器的单例池,这个对象是用来给容器中的Bean生成名字的,Spring容器new出来的时候会默认生成一个,默认的命名策略就是类名小写,不过SpringApplication中的该对象默认是null的2、SpringApplication对象有没有自定义ResourceLoader,有的话就赋值给容器,这个我们之前也分析过,默认也是null的3、addConversionService在SpringApplication对象的构造函数里就默认设置为true,所以会走if,它为容器设置了一个ConversonService,这个类是用来做类型转换的,比如String转Integer等等
开始
ConfigurationPropertySources.attach(environment);
创建了一个springAppplication对象,把传入的源文件作为参数
调用监听器的方法,并广播事件,每个阶段调用指定的方法但是发布的事件不一样,也就是ApplicationEvent的实现类不一样,所以会调用不一样的监听器这次是ApplicationEnvironmentPreparedEvent事件
加载异常解析的类
new SpringApplication(primarySources).run(args);
configureIgnoreBeanInfo(environment);
getRunListeners(args);
1--->>分析
打印启动日志
目前是得到了ApplicationContextInitializer的实现类springboot内置是7个
active-prifiles 属性加载到环境中
@Import(AutoConfigurationPackages.Registrar.class)
exceptionReporters
注意这个MainApplication.class
我理解是根据参数得到系统的环境变量,这些参数在调用run方法之前tomcat容器以及jvm系统已经处理好了,执行这个方法,就是new了一个对象,并取值已经初始化好的参数根据应用类型,创建应用环境:如得到系统的参数、JVM及Servlet等参数,等
同上得到这个接口的实现类ApplicationListener
其实就是一个封装的这个注解的注解
推断出是什么环境
这也是springboot的启动类为什么必须是main的方法名称,写别的会报错
当前类的源码解析
@Import加载时机和里面的类的源码解读
bindToSpringApplication(environment);
@SpringBootApplicationpublic class MainApplication{} 关注这个注解
@Configuration
通过反射创建这7个类的实例化对象,并做Order排序
内部处理比较复杂,总之就是加载整个项目下以及maven依赖里面的所有的META-INF/spring.factories\"下的信息
环境创建成功后,进入到configureIgnoreBeanInfo方法,就是配置了一个spring.beaninfo.ignore属性,默认为TRUE,跳过对 BeanInfo 的搜索,这个BeanInfo是JDK 声明的一个接口,可以使用Introspector.getBeanInfo获取一个对象的方法、属性、事件和其他功能的显式信息
0 条评论
回复 删除
下一页