SpringBoot启动原理——SpringApplication《课时十一》

简介: SpringBoot启动原理——SpringApplication《课时十一》

关于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依据源码分析:最终结论:

  1. 推断应用的类型是普通的项目还是Web项目。

查找并加载所有可用初始化器,设 置到initializers属性中。

找出所有的应用程序监听器,设置到listeners属性中。

更据classpath下的类 推算当前的web应用类型(webflux,servlet)  NONE,SERVLET, REACTIVE。

去SpringFactories 中获取所有的key:org.springframework.context.ApplicationContextInitializer=\

又是去SpringFactories 中获取所有的key:org.springframework.context.ApplicationListener=\

根据main推算出所在的类就是去初始化了一些信息,推断并设置main方法的定义类,找到运行的主类

理解图一

 

理解图二

相关文章
|
3天前
|
安全 Java 数据安全/隐私保护
SpringBoot实现二维码扫码登录的原理与详细步骤
SpringBoot实现二维码扫码登录的原理与详细步骤
122 1
|
3天前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
133 0
|
2天前
|
Java 开发者 Spring
springboot @RequiredArgsConstructor @Lazy解决循环依赖的原理
【5月更文挑战第16天】在Spring Boot中,@RequiredArgsConstructor 和 @Lazy 是两个有用的注解,它们分别用于简化构造函数的生成和控制Bean的加载时间。下面详细解析这两个注解的概念、优缺点以及在实际应用中的示例。
5 1
|
3天前
|
XML Java 开发者
springboot 启动原理、启动过程、启动机制的介绍
【5月更文挑战第13天】Spring Boot 是一种基于 Java 的框架,用于创建独立的、生产级别的 Spring 应用程序。它的主要目标是简化 Spring 应用的初始搭建和开发过程,同时提供一系列大型项目常见的非功能性特征(如嵌入式服务器、安全性、度量、健康检查和外部化配置)。
18 3
|
3天前
|
Java Spring 容器
SpringBoot自动装配原理之@Import注解解析
SpringBoot自动装配原理之@Import注解解析
55 0
|
3天前
|
JSON Java Maven
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
45 0
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
|
3天前
|
Java 容器 Spring
Springboot自动配置原理
Springboot自动配置原理
|
3天前
|
XML Java 应用服务中间件
总在说SpringBoot内置了tomcat启动,那它的原理你说的清楚吗
总在说SpringBoot内置了tomcat启动,那它的原理你说的清楚吗
31 0
|
3天前
|
Java API 开发者
springboot 多线程的使用原理与实战
在Spring Boot中实现多线程,主要依赖于Spring框架的@Async注解以及底层Java的并发框架。这里将深入剖析Spring Boot多线程的原理,包括@Async注解的工作方式、任务执行器的角色以及如何通过配置来调整线程行为。
73 5
|
3天前
|
消息中间件 NoSQL Java
springboot - 条件注解@ConditionalOnClass原理
springboot - 条件注解@ConditionalOnClass原理
springboot - 条件注解@ConditionalOnClass原理