Chapter 01

Spring Boot 入门

理解 IoC、DI、AOP 三大核心思想,掌握自动配置原理,动手构建第一个 RESTful 服务。

Spring 框架的历史与动机

2003 年,Rod Johnson 发布了 Spring Framework 1.0,其动机是解决 Java EE(当时叫 J2EE)中 EJB(Enterprise JavaBeans)的极度复杂性。EJB 要求开发者实现多个接口、编写大量部署描述符 XML、依赖应用服务器容器,一个简单的业务逻辑组件往往需要数十行样板代码。

Spring 的核心理念是:用普通 Java 对象(POJO)编写业务逻辑,由框架负责管理对象的生命周期和依赖关系。这种轻量级的设计大幅降低了 Java 企业应用的开发门槛。随着时间推移,Spring 生态系统不断扩大,但配置本身变得繁琐——几十个 XML 文件、大量 @Bean 配置类成为新的痛点。

2014 年,Spring Boot 1.0 发布,其核心理念是"约定优于配置"(Convention over Configuration)。Spring Boot 通过自动配置机制,使开发者只需少量注解和配置即可快速启动一个生产就绪的应用。Spring Boot 3.x 基于 Spring Framework 6.x,要求 Java 17+,原生支持 GraalVM 本机编译。

核心概念名词解释

IoC — 控制反转 (Inversion of Control)
把"创建和管理对象"的控制权从应用代码转移给框架容器。传统代码中 new UserService() 是由调用方控制的;IoC 下,容器负责创建 UserService 并在需要时注入给调用方。控制权发生了"反转"。
DI — 依赖注入 (Dependency Injection)
IoC 的具体实现方式。框架将对象所依赖的其他对象(依赖项)"注入"进来,而非由对象自己查找或创建。依赖注入让类之间的耦合度降低,便于单元测试(可注入 mock 对象)。
AOP — 面向切面编程 (Aspect-Oriented Programming)
将横切关注点(日志、事务、权限校验等)从业务逻辑中分离,以"切面"的形式统一处理。@Transactional 就是 AOP 的典型应用——Spring 用动态代理在方法执行前后自动开启/提交/回滚事务。
Bean
由 Spring IoC 容器管理的 Java 对象。通过 @Component、@Service、@Repository、@Controller 等注解,或 @Bean 方法声明的对象都会成为 Bean,容器负责其实例化、配置和生命周期管理。
ApplicationContext
Spring IoC 容器的核心接口,是 BeanFactory 的增强版。它不仅管理 Bean,还提供国际化、事件发布、资源加载等企业级功能。Spring Boot 应用启动时会自动创建一个 ApplicationContext。
@SpringBootApplication
复合注解,等价于 @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 三者的组合。标注在主类上,告诉 Spring Boot 从该类所在包开始扫描组件,并启动自动配置机制。

IoC 容器与依赖注入详解

理解 IoC 最好的方式是对比"传统方式"和"IoC 方式"。假设 OrderService 需要使用 UserService:

传统方式(紧耦合)

  • OrderService 内部 new UserService()
  • OrderService 与 UserService 强绑定
  • 无法替换为 MockUserService
  • 难以独立测试 OrderService

IoC 方式(松耦合)

  • OrderService 声明需要 UserService
  • 容器注入具体实现
  • 测试时可注入 MockUserService
  • 各组件可独立替换

三种注入方式

Spring 支持三种依赖注入方式,官方和社区均推荐构造器注入,因为它能保证依赖不可变、便于测试,且能在启动时暴露循环依赖问题。

// ✅ 推荐:构造器注入(依赖不可变,便于测试)
@Service
public class OrderService {
    private final UserService userService;
    private final OrderRepository orderRepository;

    // Spring 自动注入,单个构造器无需 @Autowired
    public OrderService(UserService userService, OrderRepository orderRepository) {
        this.userService = userService;
        this.orderRepository = orderRepository;
    }
}

// ⚠️ 不推荐:字段注入(隐藏依赖,难以测试)
@Service
public class OrderService {
    @Autowired
    private UserService userService; // 字段注入
}

Spring Boot 自动配置原理

Spring Boot 的"魔法"来源于自动配置机制。当你在 pom.xml 中添加 spring-boot-starter-web 时,Spring Boot 会自动配置好 Tomcat、Jackson、DispatcherServlet 等一系列组件,无需手动声明任何 Bean。其工作原理如下:

  1. @SpringBootApplication 包含 @EnableAutoConfiguration
  2. Spring Boot 扫描所有 JAR 包中的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 2.x 是 spring.factories)
  3. 该文件列出了数百个自动配置类,如 WebMvcAutoConfigurationDataSourceAutoConfiguration
  4. 每个配置类上有 @ConditionalOnClass@ConditionalOnMissingBean 等条件注解
  5. 只有条件满足(如 classpath 中有某个类)时,对应的 Bean 才会被创建
Info 可以通过运行 mvn spring-boot:run --debug 或在启动参数中加 --debug 来查看哪些自动配置生效了、哪些被跳过了,非常有助于排查问题。

Spring Boot 启动流程

┌─────────────────────────────────────────────────────────────────┐ │ Spring Boot 启动流程 │ └─────────────────────────────────────────────────────────────────┘ main() 方法 │ ▼ SpringApplication.run(App.class, args) │ ├── 1. 推断应用类型(SERVLET / REACTIVE / NONE) │ ├── 2. 加载 ApplicationContext Initializers │ ├── 3. 加载 ApplicationListeners │ ├── 4. 推断主配置类 │ ▼ 创建并准备 Environment(加载 application.yml / .properties) │ ▼ 打印 Banner │ ▼ 创建 ApplicationContext(AnnotationConfigServletWebServerApplicationContext) │ ├── 5. 注册 BeanDefinitions(扫描 @Component 等) │ ├── 6. 触发自动配置(AutoConfiguration) │ ├── 7. 实例化所有单例 Bean │ └── 8. 启动内嵌 Web 服务器(Tomcat 默认端口 8080) │ ▼ 应用就绪,监听请求

创建第一个 Spring Boot 应用

Tip 访问 start.spring.io 可以在线生成 Spring Boot 项目脚手架。选择 Maven / Java / Spring Boot 3.x,添加 Spring Web 依赖,下载后用 IntelliJ IDEA 或 VS Code 打开即可。

pom.xml 核心依赖

<!-- Spring Boot 父 POM,管理所有依赖版本 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
</parent>

<dependencies>
    <!-- Web: 包含 Spring MVC + Tomcat -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 开发热重载 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <!-- Lombok: 减少样板代码 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

主启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication  // 开启自动配置 + 组件扫描
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

第一个 REST Controller

package com.example.demo.controller;

import org.springframework.web.bind.annotation.*;

@RestController              // = @Controller + @ResponseBody
@RequestMapping("/api/hello")
public class HelloController {

    @GetMapping
    public String hello() {
        return "Hello, Spring Boot!";
    }

    @GetMapping("/{name}")
    public String greet(@PathVariable String name) {
        return "Hello, " + name + "!";
    }
}

推荐项目分层结构

良好的项目结构是可维护性的基础。Spring Boot 项目推荐按职责分层,各层只依赖下层,不允许跨层调用。

src/main/java/com/example/demo/ ├── DemoApplication.java # 启动类 │ ├── controller/ # 表现层:处理 HTTP 请求/响应 │ ├── UserController.java │ └── OrderController.java │ ├── service/ # 业务层:核心业务逻辑 │ ├── UserService.java # 接口 │ └── impl/ │ └── UserServiceImpl.java # 实现类 │ ├── repository/ # 数据层:数据库访问 │ └── UserRepository.java # JPA Repository 接口 │ ├── model/ # 数据模型 │ ├── entity/ │ │ └── User.java # JPA 实体 │ └── dto/ │ ├── UserCreateDTO.java # 请求 DTO │ └── UserResponseDTO.java # 响应 DTO │ ├── config/ # 配置类 │ ├── SecurityConfig.java │ └── RedisConfig.java │ └── exception/ # 自定义异常 ├── BusinessException.java └── GlobalExceptionHandler.java

application.yml 基础配置

spring:
  application:
    name: demo-service

  datasource:
    url: jdbc:postgresql://localhost:5432/demo
    username: postgres
    password: ${DB_PASSWORD}  # 从环境变量读取

  jpa:
    hibernate:
      ddl-auto: validate       # 生产环境用 validate,不自动修改表结构
    show-sql: false

server:
  port: 8080
  servlet:
    context-path: /api

logging:
  level:
    com.example.demo: DEBUG
    org.hibernate.SQL: DEBUG
Warning 不要将数据库密码、JWT Secret 等敏感信息直接写入 application.yml 并提交到代码仓库。应使用环境变量(${ENV_VAR} 语法)或 Spring Cloud Config / HashiCorp Vault 等配置中心管理。