面试基础--Spring Boot启动流程及源码实现

深度解析Spring Boot启动流程及源码实现

一、Spring Boot启动全景图(含核心阶段)

SpringApplication构造 Run方法入口 初始化事件监听器 准备环境配置 创建应用上下文 准备上下文 刷新上下文 执行Runners

二、源码级启动流程拆解

2.1 SpringApplication初始化

java 复制代码
// 源码定位:SpringApplication.java
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();
}

关键操作:

  1. 判定Web应用类型(Servlet/Reactive)
  2. 加载Spring.factories中所有ApplicationContextInitializer
  3. 加载Spring.factories中所有ApplicationListener
  4. 推断主配置类

2.2 Run方法核心流程

java 复制代码
// 源码定位:SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    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);
    }
    // 异常处理...
    return context;
}

2.3 环境准备阶段源码解析

java 复制代码
private ConfigurableEnvironment prepareEnvironment(
        SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments) {
    // 创建环境对象
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    // 配置环境(Profile处理)
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    // 触发EnvironmentPreparedEvent事件
    listeners.environmentPrepared(environment);
    bindToSpringApplication(environment);
    return environment;
}

环境处理关键点:

  1. 解析命令行参数(--server.port等)
  2. 加载application.properties/yml
  3. Profile激活处理
  4. 环境变量绑定

三、自动配置实现原理

3.1 @EnableAutoConfiguration处理流程

java 复制代码
// 源码定位:AutoConfigurationImportSelector.class
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
            annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

加载机制:

  1. 从META-INF/spring.factories加载所有配置类
  2. 执行自动配置过滤(@Conditional条件判断)
  3. 按@AutoConfigureOrder排序

3.2 条件注解处理时序

AutoConfiguration类 ConditionEvaluator CFC 检查@Conditional条件 验证类条件 验证Bean条件 验证环境条件 返回是否满足条件 AutoConfiguration类 ConditionEvaluator CFC

四、上下文刷新机制

4.1 AbstractApplicationContext.refresh() 核心流程

java 复制代码
// 源码定位:AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);
        try {
            postProcessBeanFactory(beanFactory);
            invokeBeanFactoryPostProcessors(beanFactory);
            registerBeanPostProcessors(beanFactory);
            initMessageSource();
            initApplicationEventMulticaster();
            onRefresh();
            registerListeners();
            finishBeanFactoryInitialization(beanFactory);
            finishRefresh();
        }
        // 异常处理...
    }
}

关键阶段说明:

  1. BeanFactory后置处理(处理@Configuration)
  2. BeanPostProcessor注册(AOP代理等)
  3. 内嵌Web容器启动(Tomcat/Jetty)
  4. 单例Bean预实例化

五、互联网大厂应用实践

5.1 高频扩展点实践

  1. 自定义EnvironmentPostProcessor
java 复制代码
public class CustomEnvPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment env, 
            SpringApplication app) {
        // 动态修改环境配置
    }
}
  1. 自定义FailureAnalyzer
java 复制代码
public class CustomFailureAnalyzer extends AbstractFailureAnalyzer<BeanCreationException> {
    @Override
    protected FailureAnalysis analyze(Throwable rootFailure, 
            BeanCreationException cause) {
        return new FailureAnalysis("自定义错误诊断", "解决方案建议", cause);
    }
}

5.2 启动优化策略

  1. 减少自动配置类扫描
properties 复制代码
spring.autoconfigure.exclude=com.example.unused.config.*
  1. 延迟初始化配置
properties 复制代码
spring.main.lazy-initialization=true
  1. 类加载优化
java 复制代码
@SpringBootApplication
@Configuration(proxyBeanMethods = false)
public class Application { ... }

六、深度调试技巧

  1. 启动时DEBUG参数:
bash 复制代码
java -jar app.jar --debug
  1. 条件评估报告生成:
properties 复制代码
logging.level.org.springframework.boot.autoconfigure=DEBUG
  1. 启动过程Hook注入:
java 复制代码
public static void main(String[] args) {
    new SpringApplicationBuilder(Application.class)
        .addInitializers(new ApplicationContextInitializer(){/*...*/})
        .run(args);
}

七、核心流程图总结

加载SpringFactories配置 创建Environment 准备ApplicationContext 执行BeanFactoryPostProcessor 注册BeanPostProcessor 初始化MessageSource 初始化事件广播器 执行onRefresh 注册监听器 完成Bean初始化 发布ContextRefreshedEvent

本文基于Spring Boot 3.1.0版本源码分析,完整流程图及源码示例已通过内部知识库同步。关注作者获取更多分布式架构深度解析。

相关推荐
神秘的t8 分钟前
优选算法合集————双指针(专题三)
java·数据结构·算法·二分查找
liubing518814 分钟前
解决java-jar报错:xxx.jar 中没有主清单属性的方法
java·pycharm·jar
搞不懂语言的程序员19 分钟前
数据库事务的 ACID,通过MVCC能做什么
java·开发语言·数据库
Lkkkkkkkcy25 分钟前
自己的网页加一个搜索框,调用deepseek的API
java·vue
java—大象26 分钟前
基于SpringBoot+mybatis+layui就业管理系统设计和实现
java·数据库·spring boot·后端·layui·mybatis
学编程的小鬼1 小时前
线程安全问题
java·安全
m0_748233641 小时前
MySQL的底层原理与架构
数据库·mysql·架构
居然是阿宋1 小时前
Java/Kotlin 开发者如何快速入门 C++
java·c++·kotlin
Asteroid_PZX1 小时前
JetBrains学生申请
java·intellij idea
计算机学长felix1 小时前
基于SpringBoot的“扶贫助农系统”的设计与实现(源码+数据库+文档+PPT)
spring boot·毕业设计