springboot的启动方式有2种:一种是打包jar包,java -jar启动,一种是直接运行应用的 Spring Boot 启动类的 #main(String[] args) 启动。我们这里分析的是启动类方式的启动过程。
1、从main开始
image.png
2、进入springApplication的静态run方法
image.png
以上方法创建了springApplication对象,并调用对象的run方法。
3、看看创建对象的时候做了什么
image.png
image.png
总结创建对象做了哪些事:
a、把你项目的启动类添加到SpringApplication中
b、读取springApplication当前路径下META-INF/spring.factories文件,加载ApplicationContextInitializer接口实例,加载ApplicationListener接口实例。
创建对象完毕,回到上层方法:
image.png
4、接下来调用SpringApplication对象的run方法,重点!!!
public ConfigurableApplicationContext run(String... args) {
// 非重点
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 创建环境,加载我们项目resource目录下的配置文件,最后把environment和springApplication进行绑定
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
// 设置一些环境的值
this.configureIgnoreBeanInfo(environment);
// 打印banner
Banner printedBanner = this.printBanner(environment);
// 根据项目类型创建应用上下文,并加入一些核心组件
context = this.createApplicationContext();
// 获取异常报告事件监听
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
// 准备上下,设置环境信息
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// spring初始化过程,创建并启动了内置的Tomcat容器
this.refreshContext(context);
// 空方法
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
4.1、看this.prepareEnvironment()方法
创建环境并配置环境信息,在listeners.environmentPrepared()方法中加载了我们resource目录下的配置文件。
image.png
image.png
把environment和springApplication绑定
image.png
总结this.prepareEnvironment()方法作用:
1、创建环境,加载我们项目resource目录下的配置文件,最后把environment和springApplication进行绑定。
4.2、进入this.createApplicationContext()方法
根据项目类型创建应用上下文
image.png
Web类型项目创建上下文对象是AnnotationConfigServletWebServerApplicationContext,并加入一些核心组件
image.png
总结this.createApplicationContext()方法作用:
1、根据项目类型创建应用上下文,并加入一些核心组件。
4.3、进入this.prepareContext()方法
image.png
总结this.prepareContext()方法作用:
1、把环境信息添加到上下文中
2、设置事件监听
3、bean工厂添加相关单例类
4.4、进入this.refreshContext(context)方法
image.png
等等,是不是感到莫名的熟悉!!!这是spring的初始化过程方法呀,之前我们已经分析过spring初始化过程,
请移步:https://www.jianshu.com/p/50b716c4cdb6
4.4.1、这里补充一个spring初始化过程没有实现的方法this.onRefresh(),进入到AbstractApplicationContext子类ServletWebServerApplicationContext,看看对onRefresh()方法的实现
image.png image.png
选择创建哪种类型的web容器
image.png
image.png
image.png
总结this.onRefresh()方法的作用:
1、创建并启动内置的Tomcat容器。
至此,springboot启动过程已完成
image.png
总结下这个过程重点方法:
1、SpringApplication -> new SpringApplication()
2、SpringApplication -> this.prepareEnvironment()
3、SpringApplication ->this.createApplicationContext()
4、SpringApplication -> this.prepareContext()
5、SpringApplication -> this.refreshContext()
6、AbstractApplicationContext -> this.onRefresh()
总结下以上方法主要作用:
1、创建springApplication对象,把你项目的启动类添加到SpringApplication中,读取springApplication当前路径下META-INF/spring.factories文件,加载ApplicationContextInitializer接口实例,加载ApplicationListener接口实例。
2、创建环境,加载我们项目resource目录下的配置文件,最后把environment和springApplication进行绑定。
3、根据项目类型创建应用上下文,并加入一些核心组件。
4、把环境信息添加到上下文中,设置事件监听,bean工厂添加相关单例类。
5、spring 容器初始化过程
6、创建并启动内置的Tomcat容器。
网友评论