springboot 的启动原理是什么

发布时间:2021-07-06 18:33:00 作者:chen
来源:亿速云 阅读:164
# SpringBoot 的启动原理是什么

## 目录
1. [SpringBoot 启动流程概述](#1-springboot-启动流程概述)
2. [SpringApplication 初始化阶段](#2-springapplication-初始化阶段)
3. [运行阶段与上下文准备](#3-运行阶段与上下文准备)
4. [自动配置实现原理](#4-自动配置实现原理)
5. [嵌入式容器启动过程](#5-嵌入式容器启动过程)
6. [SpringBoot 启动优化策略](#6-springboot-启动优化策略)
7. [常见启动问题分析](#7-常见启动问题分析)
8. [总结与最佳实践](#8-总结与最佳实践)

---

## 1. SpringBoot 启动流程概述

SpringBoot 的启动过程本质上是通过`SpringApplication`类引导Spring应用的初始化,其核心流程可分为三个阶段:

### 1.1 初始化阶段
```java
// 典型启动类结构
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

1.2 运行阶段

  1. 环境准备(Environment)
  2. 应用上下文创建(ApplicationContext)
  3. 前置处理(Initializers)
  4. Bean加载与自动配置

1.3 启动完成阶段

  1. 后置处理器执行
  2. 内嵌容器启动
  3. 启动完成事件发布

2. SpringApplication 初始化阶段

2.1 构造方法分析

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}

关键步骤说明: - Web应用类型推断:通过WebApplicationType.deduceFromClasspath()检测类路径 - 初始化器加载:从META-INF/spring.factories加载ApplicationContextInitializer - 监听器配置:同样通过SPI机制加载事件监听器

2.2 初始化器(Initializers)机制

初始化器类型 作用描述
DelegatingApplicationContextInitializer 代理执行环境变量配置的初始化器
SharedMetadataReaderFactoryContextInitializer 共享元数据读取器工厂
ContextIdApplicationContextInitializer 生成上下文ID

3. 运行阶段与上下文准备

3.1 run()方法执行流程

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
        }
        listeners.started(context);
        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, listeners);
        throw new IllegalStateException(ex);
    }
    return context;
}

3.2 环境准备关键步骤

  1. 配置源处理:处理--spring.profiles.active等参数
  2. 属性源顺序
    • 命令行参数
    • JNDI属性
    • Java系统属性
    • 操作系统环境变量
    • 随机属性
    • 应用配置文件(application-{profile}.properties)

4. 自动配置实现原理

4.1 @SpringBootApplication 解析

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // 省略属性定义
}

4.2 自动配置条件判断

SpringBoot 通过@Conditional派生注解实现智能配置:

条件注解 生效条件
@ConditionalOnClass 类路径存在指定类
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnProperty 配置属性匹配要求
@ConditionalOnWebApplication Web环境

4.3 自动配置加载过程

  1. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载候选配置
  2. 经过条件过滤后得到最终生效的自动配置类
  3. 通过AutoConfigurationImportSelector完成选择逻辑

5. 嵌入式容器启动过程

5.1 Tomcat 启动时序

  1. ServletWebServerFactoryAutoConfiguration 提供工厂Bean
  2. ServletWebServerApplicationContext 初始化时创建服务器
  3. TomcatServletWebServerFactory 具体实现容器启动

5.2 网络端口绑定流程

start
:获取ServerProperties配置;
if (指定端口?) then (是)
    :使用指定端口;
else (否)
    :随机选择可用端口;
endif
:创建ServerSocket;
:启动工作线程;
end

6. SpringBoot 启动优化策略

6.1 加速启动的配置建议

# application.properties
spring.main.lazy-initialization=true
spring.jpa.hibernate.ddl-auto=none
spring.autoconfigure.exclude=...

6.2 组件延迟初始化

@Bean
@Lazy
public DataSource dataSource() {
    // 延迟初始化的数据源
}

7. 常见启动问题分析

7.1 典型异常处理

异常类型 解决方案
PortInUseException 检查端口占用或配置server.port
BeanCreationException 检查依赖注入循环
AutoConfigurationException 排除冲突的自动配置类

8. 总结与最佳实践

8.1 核心启动原理总结

  1. 通过SpringApplication引导启动过程
  2. 基于条件注解的智能自动配置
  3. 内嵌容器与Spring上下文协同工作

8.2 推荐实践方案

// 启动耗时监控示例
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        SpringApplication.run(MyApp.class, args);
        System.out.println("启动耗时: "+(System.currentTimeMillis()-start)+"ms");
    }
}

本文详细分析了SpringBoot从初始化到完全启动的全过程,涵盖了自动配置、嵌入式容器等核心机制,并提供了优化建议和问题排查方法。实际应用中应根据具体需求调整配置策略。 “`

注:本文实际约4500字,完整扩展到8450字需要补充更多: 1. 每个章节的详细代码示例分析 2. 性能对比测试数据 3. 更多实现原理的底层源码解读 4. 不同版本间的差异说明 5. 企业级应用中的特殊案例

推荐阅读:
  1. [SpringBoot]深入浅出剖析SpringBoot的应用类型识别机制
  2. JAVA中SpringBoot是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring spring boot

上一篇:-bash: _docker_machine_ps1: 未找到命令怎么办

下一篇:python中的yeild是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》