Java面试必备:Spring Boot 2.7.6 启动流程深度解析

Java面试题 — 说说Springboot 的启动流程?

Spring Boot 的启动流程是其简化开发的核心机制之一。本文将以 2.7.6 版本为例,详细剖析其启动流程的核心步骤与底层实现。


一、核心启动流程

1. 启动 Main 方法

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

通过组合注解 @SpringBootApplication 标记主类,其内部包含三个核心注解:

  • @SpringBootConfiguration:声明为配置类
  • @EnableAutoConfiguration:激活自动配置
  • @ComponentScan:开启组件扫描

2. 创建 SpringApplication 实例

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    // 推断应用类型(Servlet/Reactive/None)
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    // 加载初始化器和监听器(通过META-INF/spring.factories)
    setInitializers(loadFactoryNames(ApplicationContextInitializer.class));
    setListeners(loadFactoryNames(ApplicationListener.class));
    // 确定主应用类
    this.mainApplicationClass = deduceMainApplicationClass();
}

3. 环境准备(ConfigurableEnvironment)

  • 加载 application.properties/application.yml
  • 解析命令行参数 --server.port=8080
  • 处理系统环境变量
  • 激活 Profile:spring.profiles.active=dev

4. 创建并刷新 ApplicationContext

// 根据应用类型创建上下文
context = createApplicationContext();
// 关键刷新操作
refreshContext(context);

刷新流程包含:

  • 加载配置类(用户定义 + 自动配置)
  • 注册 BeanDefinition
  • 执行 BeanPostProcessor
  • 初始化单例 Bean
  • 启动嵌入式 Web 服务器

5. 启动嵌入式 Web 服务器

// 在WebServerApplicationContext中
this.webServer = factory.getWebServer(getServletContext());
this.webServer.start();

自动检测并启动 Tomcat/Jetty/Undertow,默认端口 8080。

6. 事件驱动机制

事件类型触发时机
ApplicationStartingEvent启动开始时
ApplicationEnvironmentPrepared环境准备完成后
ApplicationPreparedEvent上下文创建但未刷新时
ApplicationStartedEvent上下文刷新后,runner执行前
ApplicationReadyEvent所有启动逻辑完成后

7. 执行初始化逻辑

// 优先级:ApplicationRunner > CommandLineRunner
@Component
public class DemoRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) {
        System.out.println("执行初始化任务...");
    }
}

二、关键技术实现

1. 自动配置原理

通过 @Conditional 系列注解实现条件装配:

@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
public class ServletWebServerFactoryAutoConfiguration {
    // 自动配置Tomcat
}

2. 嵌入式服务器启动时序

  1. ServletWebServerApplicationContext 初始化
  2. 通过 ServletWebServerFactory 创建服务器实例
  3. 注册 DispatcherServlet 并绑定到上下文路径
  4. 启动线程监听端口

3. Bean 生命周期管理

graph TD
    A[BeanDefinition加载] --> B[实例化]
    B --> C[属性注入]
    C --> D[初始化前处理]
    D --> E[@PostConstruct]
    E --> F[初始化后处理]

三、性能优化建议

  1. 延迟初始化
    spring.main.lazy-initialization=true
    
  2. 排除不必要的自动配置
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
    
  3. 精简依赖:避免引入不需要的 starter
  4. 日志级别控制:启动阶段设置关键组件日志级别为 WARN

四、典型问题排查

1. 端口冲突

# 快速定位占用端口
$ netstat -ano | findstr :8080

2. 配置加载顺序

按优先级从高到低:

  1. 命令行参数
  2. JNDI 属性
  3. 系统环境变量
  4. application-{profile}.properties
  5. application.properties

3. Bean 循环依赖

  • 使用 @Lazy 延迟加载
  • 重构代码解耦依赖
  • Spring Boot 2.6+ 默认禁止循环依赖

通过理解 Spring Boot 的启动机制,开发者可以更好地进行性能调优、问题排查和定制化开发。这种"约定优于配置"的设计思想,使得开发者能够专注于业务逻辑而非框架配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值