关于SpringApplication类的作用有两个结论
推荐:画流程图的软件 下载Boardmix协同设计工具 - Boardmix官网
结论一:SpringApplication类的作用
- 1.推断应用的类型是普通的项目还是Web项目
- 2.查找并加载所有可用初始化器,设 置到initializers属性中.
- 3 找出所有的应用程序监听器,设置到listeners属性中
- 4.推断并设置main方法的定义类,找到运行的主类
结论二:SpringApplication类的作用
- 1.获取启动类
- 2.获取web应用类型
- 3.读取了对外扩展的Applcation Contextintializer ,ApplicationListener
- 4.根据main推算出所在的类就是去初始化了一些信息
官网介绍:
Spring Boot Features 找到1.7的介绍
官网介绍的SpringBoot启动原理该如何启动 翻译在下面的文章中
当您的应用程序运行时,应用程序事件按以下顺序发送:
ApplicationStartingEvent在运行开始时但在任何处理之前发送,除了侦听器和初始化程序的注册。
ApplicationEnvironmentPreparedEvent当Environment在上下文中使用的 已知但在创建上下文之前发送一个。
ApplicationContextInitializedEvent当ApplicationContext准备好并调用 ApplicationContextInitializers 但在加载任何 bean 定义之前发送一个。
ApplicationPreparedEvent在刷新开始之前但在加载 bean 定义之后发送一个。
AnApplicationStartedEvent在上下文刷新之后但在调用任何应用程序和命令行运行程序之前发送。
AvailabilityChangeEvent在 with 之后立即发送一个LivenessState.CORRECT,表明应用程序被认为是活动的。
ApplicationReadyEvent在调用任何应用程序和命令行运行程序后发送一个。
AvailabilityChangeEvent在 with 之后立即发送一个ReadinessState.ACCEPTING_TRAFFIC,表示应用程序已准备好为请求提供服务。
如果ApplicationFailedEvent启动时出现异常,则发送一个。
这篇文章在解释SpringApplication类的作用:
package com.spring.springboot0907web; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //深入源码 解析SpringBoot自动配置原理 @SpringBootApplication public class Springboot0907WebApplication { public static void main(String[] args) { //解析SpringBoot启动原理 SpringApplication.run(Springboot0907WebApplication.class, args); } }
关注点在上面的代码中
按住Ctrl键:点击进入Run方法
如图所示进入上面的页面
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return (new SpringApplication(primarySources)).run(args); }
使用自定义的Spring Application 进行启动程序
按住Ctrl键:点击进入SpringApplication 进入下面的页面信息
按住 ctrl 进入 this
解析下面的源码 来得出我们自己的结论:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.addConversionService = true; this.headless = true; this.registerShutdownHook = true; this.additionalProfiles = Collections.emptySet(); this.isCustomEnvironment = false; this.lazyInitialization = false; this.applicationContextFactory = ApplicationContextFactory.DEFAULT; this.applicationStartup = ApplicationStartup.DEFAULT; this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class)); this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = this.deduceMainApplicationClass(); }
1 将启动类放在 primarySources 放在哪里干吗 接着往下看
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
2 更据classpath下的类 推算当前的web应用类型(webflux,servlet) NONE,SERVLET, REACTIVE;
this.webApplicationType = WebApplicationType.deduceFromClasspath(); //点击进去 WebApplicationType 如下所示
public enum WebApplicationType { NONE, SERVLET, REACTIVE; private static final String[] SERVLET_INDICATOR_CLASSES = new String[]{"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"}; private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet"; private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler"; private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer"; private WebApplicationType() { }
3 又是去SpringFactories 中获取所有的key:org.springframework.context.ApplicationContextInitializer=\
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
4 又是去SpringFactories 中获取所有的key:org.springframework.context.ApplicationListener=\
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
5 根据main方法推算出mainApplicationClass
this.mainApplicationClass = this.deduceMainApplicationClass();
观察下面上面的图
SpringApplication依据源码分析:最终结论:
- 推断应用的类型是普通的项目还是Web项目。
查找并加载所有可用初始化器,设 置到initializers属性中。
找出所有的应用程序监听器,设置到listeners属性中。
更据classpath下的类 推算当前的web应用类型(webflux,servlet) NONE,SERVLET, REACTIVE。
去SpringFactories 中获取所有的key:org.springframework.context.ApplicationContextInitializer=\
又是去SpringFactories 中获取所有的key:org.springframework.context.ApplicationListener=\
根据main推算出所在的类就是去初始化了一些信息,推断并设置main方法的定义类,找到运行的主类
理解图一
理解图二