SpringBoot源码分析系列之二:启动原理分析

简介: 我们都知道SpringBoot是目前微服务比较流行的技术选型,它可以将工程打成war包的方式在tomcat进行启动,也可以打成jar包,直接对外提供服务。那我们就会好奇,它是怎么去启动服务的,同时是怎么去加载前端页面、js文件、配置文件以及class文件等等然后向外提供web服务的。带着一系列的疑问,一步步探究SpringBoot的启动原理。SpringBoot大致启动流程源码跟踪分析总结

引言

我们都知道SpringBoot是目前微服务比较流行的技术选型,它可以将工程打成war包的方式在tomcat进行启动,也可以打成jar包,直接对外提供服务。那我们就会好奇,它是怎么去启动服务的,同时是怎么去加载前端页面、js文件、配置文件以及class文件等等然后向外提供web服务的。带着一系列的疑问,一步步探究SpringBoot的启动原理。

  • SpringBoot大致启动流程
  • 源码跟踪分析
  • 总结

1.SpringBoot大致启动流程如下图所示。

3.png

2.源码跟踪分析

(1)main函数为主程序入口,SpringApplication调用run方法来启动SpringBoot服务。注解的含义在上一篇文章中进行了说明,这里不再赘述。

@SpringBootApplication(scanBasePackages = {"com.hikvision.center"})
@MapperScan("com.hikvision.center.module.mapper")
@ImportResource(locations = {"classpath:springMVC-servlet.xml"})
@ServletComponentScan
public class WebApplication extends SpringBootServletInitializer{
  static Logger logger = LoggerFactory.getLogger(WebApplication.class);
  public static void main(String[] args) {
          //程序入口
      SpringApplication.run(WebApplication.class, args);
  }
}

(2)run方法是一个静态方法,主要执行一系列的初始化加载操作。

 //
public static ConfigurableApplicationContext run(Object source, String... args) {
  return run(new Object[] { source }, args);
}

(3)ConfigurableApplicationContext表示该 Context 是可修改的,也就是在构建 Context中用户可以动态添加或修改已有的配置信息。下图为ApplicationContext类关系图。

image.png

//创建了SpringApplication实例,同时调用run方法
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
  return new SpringApplication(sources).run(args);
}

(4)初始化操作。

//SpringApplication构造函数中,进行初始化操作,上下文从指定的源中加载bean,实例可以在被调用前进行自定义
public SpringApplication(Object... sources) {
    initialize(sources);
  }

(5)主要是为SpringApplication对象赋一些初值。

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
  if (sources != null && sources.length > 0) {
    this.sources.addAll(Arrays.asList(sources));
  }
  //判断当前允许的环境是否为web环境
  this.webEnvironment = deduceWebEnvironment();
  //
  setInitializers((Collection) getSpringFactoriesInstances(
      ApplicationContextInitializer.class));
  //
  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  //
  this.mainApplicationClass = deduceMainApplicationClass();
}

(6)回到run方法中去看具体的实现,该方法主要完成ApplicationContext配置加载。

public ConfigurableApplicationContext run(String... args) {
  //性能检查,查看代码的运行时间
  StopWatch stopWatch = new StopWatch();
  stopWatch.start();
  //设置上下文ID,设置父应用上下文,添加监听器和刷新容器相关的操作等
  ConfigurableApplicationContext context = null;
  //异常分析器
  FailureAnalyzers analyzers = null;
  //设置java.awt.headless属性,
  configureHeadlessProperty();
  //创建应用监听器SpringApplicationRunListeners同时开始监听
  SpringApplicationRunListeners listeners = getRunListeners(args);
  //启动监听器
  listeners.started();
  try {
    //获取启动参数
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(
        args);
    //加下SpringBoot配置环境
    ConfigurableEnvironment environment = prepareEnvironment(listeners,
        applicationArguments);
    //定义输出的标志,打印spring
    Banner printedBanner = printBanner(environment);
    //创建应用上下文
    context = createApplicationContext();
    //注册异常分析器
    analyzers = new FailureAnalyzers(context);
    //为ApplicationContext加载environment,初始化IoC容器,调用SpringApplicationRunListener的contextLoaded()方法,完成IOC容器加载
    prepareContext(context, environment, listeners, applicationArguments,
        printedBanner);
    //初始化自动配置
    refreshContext(context);
    //SpringBoot完成ApplicationContext初始化
    afterRefresh(context, applicationArguments);
    //广播已经完成初始化全部过程
    listeners.finished(context, null);
    //关闭任务执行还见监听器
    stopWatch.stop();
    if (this.logStartupInfo) {
      new StartupInfoLogger(this.mainApplicationClass)
          .logStarted(getApplicationLog(), stopWatch);
    }
    return context;
  }
  catch (Throwable ex) {
    handleRunFailure(context, listeners, analyzers, ex);
    throw new IllegalStateException(ex);
  }
}

3.总结

从以上Springboot启动过程来看,它主要创建了程序配置环境(environment)、事件监听(listeners)、应用上下文(applicationContext),并在以上基础上,在容器中开始加载和实例化我们需要的Bean,在这些过程中有些过程是可以自定义的。


相关文章
|
29天前
|
Dart 前端开发 JavaScript
springboot自动配置原理
Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
61 17
springboot自动配置原理
|
30天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
41 5
|
2月前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
2月前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
153 14
|
3月前
|
Java 容器
springboot自动配置原理
启动类@SpringbootApplication注解下,有三个关键注解 (1)@springbootConfiguration:表示启动类是一个自动配置类 (2)@CompontScan:扫描启动类所在包外的组件到容器中 (3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效
|
3月前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
57 0
|
3月前
|
Java Spring
SpringBoot自动装配的原理
在Spring Boot项目中,启动引导类通常使用`@SpringBootApplication`注解。该注解集成了`@SpringBootConfiguration`、`@ComponentScan`和`@EnableAutoConfiguration`三个注解,分别用于标记配置类、开启组件扫描和启用自动配置。
79 17
|
4月前
|
Java Spring 容器
springboot @RequiredArgsConstructor @Lazy解决循环依赖的原理
【10月更文挑战第15天】在Spring Boot应用中,循环依赖是一个常见问题,当两个或多个Bean相互依赖时,会导致Spring容器陷入死循环。本文通过比较@RequiredArgsConstructor和@Lazy注解,探讨它们解决循环依赖的原理和优缺点。@RequiredArgsConstructor通过构造函数注入依赖,使代码更简洁;@Lazy则通过延迟Bean的初始化,打破创建顺序依赖。两者各有优势,需根据具体场景选择合适的方法。
213 4
|
4月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
908 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
4月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
323 2