一、核心概念

1. SpringApplication

Spring Boot 启动的核心类。它封装了应用上下文创建、环境准备、自动配置、内嵌服务器启动等逻辑。

2. @SpringBootApplication 注解

这是启动类上的关键注解,它是一个组合注解,等价于:

@Configuration      // 标识为配置类
@EnableAutoConfiguration  // 启用自动配置
@ComponentScan      // 扫描当前包及其子包下的组件

3. 应用上下文(ApplicationContext)

Spring 容器的核心,负责管理 Bean 的生命周期、依赖注入、事件发布等。

4. 自动配置(Auto-configuration)

Spring Boot 根据 classpath 中的依赖自动配置 Bean,例如:

  • 存在 spring-boot-starter-web → 自动配置 Tomcat + Spring MVC
  • 存在 spring-boot-starter-data-jpa → 自动配置 DataSource、EntityManager

5. 内嵌服务器(Embedded Server)

默认内嵌 Tomcat,也可替换为 Jetty 或 Undertow,无需部署 WAR 包。


二、Spring Boot 启动流程(详细步骤)

启动流程从 main 方法开始,以下是超详细步骤分解

步骤 1:调用 SpringApplication.run()

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

步骤 2:创建 SpringApplication 实例

  • 设置主配置类(primarySource = DemoApplication.class
  • 推断应用类型(Web Application、Reactive、Non-Web)
  • 加载 ApplicationContextInitializerApplicationListener
  • 设置主类(用于推断 package)

📌 此时还未创建容器。


步骤 3:执行 run() 方法(核心流程)

3.1 创建并配置 Environment(环境)

  • 创建 StandardServletEnvironment(Web 应用)
  • 加载配置源:
    • application.properties / application.yml
    • 命令行参数(--server.port=8081
    • 系统属性、环境变量
  • 激活 Profile(spring.profiles.active=dev

3.2 创建 ApplicationContext

根据应用类型创建:

  • AnnotationConfigServletWebServerApplicationContext(Web)
  • AnnotationConfigReactiveWebServerApplicationContext(WebFlux)
  • AnnotationConfigApplicationContext(非 Web)

3.3 prepareContext():准备上下文

  • Environment 关联到 ApplicationContext
  • 调用 ApplicationContextInitializer(如有)
  • 注册主配置类(DemoApplication)为 Bean
  • 扫描组件(@ComponentScan

3.4 refreshContext():刷新上下文(Spring 核心)

这是 Spring 框架的核心流程,包括:

  1. invokeBeanFactoryPostProcessors

    • 执行 BeanFactoryPostProcessor,如 ConfigurationClassPostProcessor
    • 解析 @Configuration@Import@ComponentScan 等注解
    • 关键:处理 @EnableAutoConfiguration
      • 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 3.x)
      • spring.factories(Spring Boot 2.x)
      • 加载所有自动配置类(如 WebMvcAutoConfiguration
  2. registerBeanPostProcessors
    注册 Bean 后置处理器(如 AutowiredAnnotationBeanPostProcessor

  3. finishBeanFactoryInitialization

    • 实例化所有非懒加载的单例 Bean
    • 执行 @Bean 方法
    • 依赖注入(@Autowired
    • 调用 InitializingBean.afterPropertiesSet()@PostConstruct
  4. finishRefresh()

    • 发布 ContextRefreshedEvent
    • 启动内嵌 Web 服务器(Tomcat/Jetty)

3.5 启动内嵌服务器

  • 创建 ServletWebServerFactory(如 TomcatServletWebServerFactory
  • 创建 Tomcat 实例
  • 将 Spring MVC 的 DispatcherServlet 注册到 Tomcat
  • 启动 Tomcat,监听端口(默认 8080)

3.6 执行 ApplicationRunnerCommandLineRunner

  • @Order 或实现 Ordered 接口顺序执行
  • 用于启动后执行自定义逻辑(如数据初始化)

3.7 发布 ApplicationReadyEvent

  • 标志应用已准备好接收请求
  • 可监听此事件做最后处理

三、常见错误与解决方案

错误现象 原因 解决方案
APPLICATION FAILED TO START 配置错误、端口占用、Bean 冲突 查看日志定位具体原因
Port 8080 already in use 端口被占用 修改 server.port=8081 或关闭占用进程
NoSuchBeanDefinitionException Bean 未注册 检查 @Component, @Service 是否在扫描路径下
Failed to configure a DataSource 缺少数据库配置 添加 spring.datasource.url 或使用 @SpringBootTest
Circular dependency 循环依赖 使用 @Lazy 或重构设计
ClassNotFoundException: Servlet 缺少 Web 依赖 确保添加 spring-boot-starter-web

四、注意事项

  1. 主类位置@SpringBootApplication 类应放在根包下,确保 @ComponentScan 能扫描到所有组件。
  2. 自动配置冲突:避免手动配置与自动配置 Bean 冲突(如手动定义 DataSource 但未排除 DataSourceAutoConfiguration)。
  3. Profile 激活
    • 优先级:命令行 > 环境变量 > application.properties
    • 多 Profile:spring.profiles.active=dev,metrics
  4. DevTools 影响
    • 启用热部署,但会禁用缓存(如 Thymeleaf 缓存)
    • 生产环境不要包含 spring-boot-devtools
  5. 日志级别:生产环境设置 logging.level.root=WARN,避免日志过多。

五、使用技巧

src/main/resources/ 下创建 banner.txt,内容将显示在启动日志顶部。

2. 启动时执行代码

@Component
public class StartupRunner implements CommandLineRunner {
    @Override
    public void run(String... args) {
        System.out.println("应用启动完成,执行初始化任务...");
    }
}

3. 条件化配置

@Configuration
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public class FeatureConfig { ... }

4. 排除自动配置

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

5. 监听启动事件

@Component
public class StartupListener {
    @EventListener
    public void handleContextRefresh(ContextRefreshedEvent event) {
        System.out.println("上下文刷新完成");
    }
}

六、最佳实践与性能优化

最佳实践

  1. 分层清晰

    • Controller → Service → Repository
    • 使用 @Controller, @Service, @Repository 明确职责
  2. 异常统一处理

    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(Exception.class)
        public ResponseEntity<String> handle(Exception e) {
            return ResponseEntity.status(500).body(e.getMessage());
        }
    }
    
  3. 配置外化

    • 敏感信息使用环境变量:SPRING_DATASOURCE_PASSWORD=xxx
    • 多环境配置:application-dev.yml, application-prod.yml
  4. 健康检查

    • 添加 spring-boot-starter-actuator
    • 访问 /actuator/health 监控应用状态
  5. 日志结构化

    • 使用 JSON 格式日志,便于 ELK 收集
    • 配置:logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n

性能优化建议

优化项 配置示例 说明
Gzip 压缩 server.compression.enabled=true 减少响应体积
连接池优化 spring.datasource.hikari.maximum-pool-size=20 避免连接不足
JVM 调优 -Xms512m -Xmx1024m -XX:+UseG1GC 生产环境设置堆大小和 GC
缓存 使用 @Cacheable + Redis 减少数据库压力
异步处理 @Async + @EnableAsync 提升吞吐量
Actuator 监控 management.endpoints.web.exposure.include=* 实时监控性能指标

七、扩展:Spring Boot 3.x 新特性(基于 Java 17+)

  1. Jakarta EE 9+:包名从 javax.*jakarta.*
  2. GraalVM 原生镜像支持:通过 native-image 编译为原生可执行文件,启动更快、内存更小。
  3. 新的自动配置机制:使用 spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 替代 spring.factories
  4. Micrometer 2.0:更强大的指标监控。

总结

Spring Boot 启动流程虽复杂,但其设计精巧,通过自动配置和约定优于配置原则极大简化了开发。掌握其核心流程,有助于:

  • 快速定位启动问题
  • 理解 Bean 加载顺序
  • 优化应用性能
  • 实现高级定制(如自定义 Starter)

动手实践建议

  1. 创建一个最简项目,逐步添加依赖观察启动日志变化
  2. 使用 --debug 参数启动,查看自动配置报告
  3. 尝试排除某个 AutoConfiguration,观察行为变化