介绍:本文使用Spring Boot 2.3.1.RELEASE 讲解
1.启动类(这个谁都知道)
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}
2.当启动的时候我们点进run的这个方法的时候会先创建一个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)); //这个是用来判断当前spring boot项目是什么类型(Reactive、NONE、Servlet)通常是Servlet类型 this.webApplicationType = WebApplicationType.deduceFromClasspath(); //创建SpringApplication实例重点是这两个方法:进行了程序前期的设置初始化过程和设置监听器过程 //getSpringFactoriesInstances这个方法在spring boot出现过很多次用处是获取springboot的spring.factories文件下的类列表:详情看注解1 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
这个方法做了什么呢?
注解1:获取spring.factories这个指定类下的类
3.当SpringApplication的实例创建完成后继续调用run方法
public ConfigurableApplicationContext run(String... args) { //这个不用说就是计时器,看你项目什么时候启动开始时间 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection exceptionReporters = new ArrayList<>(); //设置headless configureHeadlessProperty(); //1.这个方法当我们点击进去 //2.我们就可以看到熟悉的getSpringFactoriesInstances()方法 //3.获取spring.factories文件下 //4.SpringApplicationRunListener.class类的列表就是监听器列表 //5.监听器列表在Spring Boot也很重要,标志这你到哪里做什么事。 //6.就等于你6岁要上学了,20岁要结婚了的意思 SpringApplicationRunListeners listeners = getRunListeners(args); //这个就是监听器的starting方法告诉别人监听器开始工作了 //1.当点进去的时候你会发现是一个监听器列表迭代使用starting方法 //2.而starting方法又是SpringApplicationRunListener.java接口 //3.所以代表基本所有Spring监听都实现了该接口方法 listeners.starting(); try { //1.这个ApplicationArguments是个接口类, //2.Spring Boot有默认的实现类通常Default*开头 //3.(例如DefaultBeanDefinitionDocumentReader、DefaultListableBeanFactory等) ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //1.准备环境变量,在不同的机器获取当前运行环境、 //2.并且运行listeners.environmentPrepared(environment); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); //这个大家都知道打印Banner图 Banner printedBanner = printBanner(environment); //1.创建应用程序上下文,上下文可以理解意思就是整个spring boot项目 //2.进入到该方法会发现用到创建SpringApplication实例当时获取的当前项目类型(Servlet还是Reactive) context = createApplicationContext(); //加载SpringBoot异常报告器 exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); //这个重点了,准备上下文 prepareContext(context, environment, listeners, applicationArguments, printedBanner); //这个也是重点,刷新上下文 refreshContext(context); afterRefresh(context, applicationArguments); //停止计时器 stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } //监听器started状态 listeners.started(context); //可以分别实现ApplicationRunner.java接口和CommandLineRunner.java接口进行实现 //这个方法很简单可以进去看看 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } //整个Spring Boot流程加载完成返回上下文 return context; }
小结:
1.这是作者的第一篇分享的文章,可能排版内容还有很多都不是特别好。欢迎大家批评。
2.关于Spring Boot启动流程,这是最基本的流程,具体里面怎么跑我们下一章再仔细探讨
Kakki
一个喜欢写Bug的码农