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

发布于:2025-03-05 ⋅ 阅读:(16) ⋅ 点赞:(0)

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

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

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

二、源码级启动流程拆解

2.1 SpringApplication初始化

// 源码定位: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方法核心流程

// 源码定位: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 环境准备阶段源码解析

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处理流程

// 源码定位: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() 核心流程

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

5.2 启动优化策略

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

六、深度调试技巧

  1. 启动时DEBUG参数:
java -jar app.jar --debug
  1. 条件评估报告生成:
logging.level.org.springframework.boot.autoconfigure=DEBUG
  1. 启动过程Hook注入:
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版本源码分析,完整流程图及源码示例已通过内部知识库同步。关注作者获取更多分布式架构深度解析。