Skip to content

Spring Boot

一、为什么需要 Spring Boot?

Spring 框架虽然强大,但配置极其繁琐:需要手动配置数据源、事务管理器、视图解析器、DispatcherServlet……每个项目都要复制粘贴大量 XML/Java 配置。

Spring Boot 的核心是约定优于配置:默认配置覆盖 90% 场景,你只需关注业务代码。它的三大武器:自动配置、起步依赖、内嵌服务器。

二、自动配置

2.1 原理

@SpringBootApplication 是个组合注解:

java
@SpringBootConfiguration   // 标记为配置类
@EnableAutoConfiguration   // 开启自动配置(核心)
@ComponentScan             // 组件扫描

@EnableAutoConfiguration 的工作原理:

  1. 通过 @Import(AutoConfigurationImportSelector.class) 导入选择器
  2. 选择器读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件
  3. 文件中列出了所有自动配置类(约 150+ 个)
  4. 每个自动配置类上有 @Conditional 系列注解,条件满足时才生效
java
// 示例:Spring Boot 自动配置数据源的简化逻辑
@AutoConfiguration
@ConditionalOnClass(DataSource.class)  // 类路径有 DataSource
@ConditionalOnMissingBean(DataSource.class)  // 用户没自己定义 DataSource
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
    @Bean
    public DataSource dataSource(DataSourceProperties props) {
        // 根据 spring.datasource.* 配置创建 DataSource
        return props.initializeDataSourceBuilder().build();
    }
}

2.2 @Conditional 条件注解

注解条件
@ConditionalOnClass类路径存在指定类
@ConditionalOnMissingBean容器中不存在指定 Bean
@ConditionalOnProperty配置项有指定值
@ConditionalOnBean容器中存在指定 Bean
@ConditionalOnMissingClass类路径不存在指定类
@ConditionalOnExpressionSpEL 表达式为 true

为什么需要这些条件注解? 让自动配置"智能":你引入了 HikariCP → 自动配置 HikariCP;你自定义了 DataSource Bean → 自动配置退让,不覆盖你的配置。

三、起步依赖

3.1 原理

为什么引入 spring-boot-starter-web 就能开发 Web 应用?

起步依赖是 Maven 的依赖传递。spring-boot-starter-web 聚合了 Spring MVC、Tomcat、Jackson、Validation 等所有 Web 开发需要的依赖,版本由 Spring Boot 统一管理,避免版本冲突。

xml
<!-- 传统 Spring:手动引入几十个依赖,版本冲突常见 -->
<!-- Spring Boot:一个起步依赖搞定 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.2 常用起步依赖

起步依赖功能
spring-boot-starter-webWeb 开发(MVC + Tomcat)
spring-boot-starter-data-jpaJPA + Hibernate
spring-boot-starter-data-redisRedis
spring-boot-starter-test测试(JUnit + Mockito)
spring-boot-starter-actuator监控端点
spring-boot-starter-aopAOP

四、内嵌服务器

为什么开发时不需要装 Tomcat? Spring Boot 内嵌了 Tomcat/Jetty/Undertow,应用直接以 main 方法启动,不需要部署 war 包到外部容器。

java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);  // 内嵌 Tomcat 启动
    }
}

好处:

  1. 一条命令启动,无需预装 Tomcat
  2. 每个应用独立 Tomcat 实例,隔离性好
  3. Docker 友好,一个 jar 就是整个应用

五、配置管理

5.1 配置优先级

Spring Boot 支持多种配置源,优先级从高到低:

命令行参数 > Java 系统属性 > 操作系统环境变量
  > application-{profile}.yml(外部) > application-{profile}.yml(内部)
  > application.yml(外部) > application.yml(内部)
  > @PropertySource 加载的配置

5.2 多环境配置

yaml
# application.yml(公共配置)
spring:
  application:
    name: order-service

---
# application-dev.yml(开发环境)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dev_db

---
# application-prod.yml(生产环境)
spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/order_db

通过 spring.profiles.active=dev 激活对应环境。

5.3 @ConfigurationProperties

java
@Component
@ConfigurationProperties(prefix = "app.order")
public class OrderProperties {
    private int timeout = 30;        // 默认值
    private int maxRetry = 3;
    private String callbackUrl;
    // getter/setter
}
yaml
app:
  order:
    timeout: 60
    callback-url: https://api.example.com/callback

六、Actuator 监控

为什么需要 Actuator? 生产环境需要知道应用的健康状态、内存使用、线程情况等。Actuator 提供开箱即用的监控端点:

端点说明
/actuator/health健康检查(数据库、Redis 连通性)
/actuator/metrics指标(JVM 内存、GC、HTTP 请求)
/actuator/beans容器中的 Bean 列表
/actuator/env环境配置
/actuator/loggers运行时修改日志级别
/actuator/threaddump线程快照
yaml
management:
  endpoints:
    web:
      exposure:
        include: health,metrics,loggers  # 暴露的端点
  endpoint:
    health:
      show-details: always                # 显示详情

七、面试要点

Q:Spring Boot 的自动配置原理?

@EnableAutoConfiguration 通过 AutoConfigurationImportSelector 加载 spring.factories 中声明的自动配置类,配合 @Conditional 条件注解决定哪些配置生效。

Q:Spring Boot 和 Spring 的区别?

Spring 是框架,需要大量手动配置;Spring Boot 是 Spring 的快速启动器,提供自动配置、起步依赖、内嵌服务器,开箱即用。

Q:Spring Boot 如何处理跨域?

@CrossOrigin 注解在 Controller 上,或全局配置 WebMvcConfigurer.addCorsMappings()

Q:如何自定义 starter?

创建自动配置模块,在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中声明自动配置类,配合 @Conditional@ConfigurationProperties。使用时引入该 starter 即可自动生效。