Skip to content

第57课:Spring Boot 基础

🎯 学习目标

  • 理解 Spring Boot 的核心理念
  • 掌握 Spring Boot 项目的创建和配置
  • 理解自动配置原理
  • 掌握 application.yml 配置
  • 理解 Profile 多环境配置

📖 一、Spring Boot 是什么?

1. 传统 Spring 的痛点

xml
<!-- 传统 Spring 需要大量 XML 配置 -->
<beans>
    <bean id="dataSource" class="...">
        <property name="url" value="..."/>
        <property name="username" value="..."/>
        <property name="password" value="..."/>
    </bean>
    
    <bean id="sqlSessionFactory" class="...">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 还有几十行配置... -->
</beans>

2. Spring Boot 的解决方案

java
// Spring Boot:零配置启动
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 只需一个注解,自动配置完成!

3. Spring Boot 的核心特性

  • 约定优于配置:提供默认配置,开箱即用
  • 自动配置:根据依赖自动配置 Bean
  • 起步依赖:一个 starter 解决一类功能
  • 内嵌服务器:无需部署 WAR 包
  • 生产就绪:内置监控、健康检查

📖 二、创建 Spring Boot 项目

方式1:Spring Initializr(推荐)

访问 https://start.spring.io/

配置:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.0
- Packaging: Jar
- Java: 17

Dependencies:
- Spring Web
- Spring Data JPA
- MySQL Driver
- Lombok

方式2:IDEA 创建

File → New → Project → Spring Initializr
填写 Group、Artifact、Name
选择依赖

方式3:Maven 手动创建

pom.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <!-- 继承 Spring Boot 父项目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0.0</version>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Web 起步依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- Spring Boot Maven 插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

📖 三、项目结构

demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/demo/
│   │   │       ├── DemoApplication.java      # 启动类
│   │   │       ├── controller/               # 控制层
│   │   │       ├── service/                  # 业务层
│   │   │       ├── repository/               # 数据访问层
│   │   │       ├── entity/                   # 实体类
│   │   │       ├── dto/                      # 数据传输对象
│   │   │       ├── vo/                       # 视图对象
│   │   │       ├── config/                   # 配置类
│   │   │       └── exception/                # 异常处理
│   │   └── resources/
│   │       ├── application.yml               # 主配置文件
│   │       ├── application-dev.yml           # 开发环境
│   │       ├── application-prod.yml          # 生产环境
│   │       ├── static/                       # 静态资源
│   │       └── templates/                    # 模板文件
│   └── test/
│       └── java/
│           └── com/example/demo/
│               └── DemoApplicationTests.java
├── pom.xml
└── README.md

📖 四、启动类详解

java
package com.example.demo;

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

/**
 * Spring Boot 启动类
 * 
 * @SpringBootApplication 是组合注解,包含:
 * - @SpringBootConfiguration: 标记为配置类
 * - @EnableAutoConfiguration: 启用自动配置
 * - @ComponentScan: 扫描当前包及子包的组件
 */
@SpringBootApplication
public class DemoApplication {
    
    public static void main(String[] args) {
        // 启动 Spring Boot 应用
        SpringApplication.run(DemoApplication.class, args);
    }
}

启动类的变体

java
// 1. 自定义扫描路径
@SpringBootApplication(scanBasePackages = "com.example")
public class DemoApplication { }

// 2. 排除自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DemoApplication { }

// 3. 自定义启动
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(DemoApplication.class);
        app.setBannerMode(Banner.Mode.OFF);  // 关闭启动横幅
        app.run(args);
    }
}

📖 五、第一个 REST API

1. 创建 Controller

java
package com.example.demo.controller;

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

@RestController  // @Controller + @ResponseBody
@RequestMapping("/api")
public class HelloController {
    
    // GET 请求:http://localhost:8080/api/hello
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }
    
    // GET 请求带参数:http://localhost:8080/api/greet?name=Alice
    @GetMapping("/greet")
    public String greet(@RequestParam String name) {
        return "Hello, " + name + "!";
    }
    
    // 路径变量:http://localhost:8080/api/user/123
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        return "User ID: " + id;
    }
    
    // POST 请求
    @PostMapping("/user")
    public String createUser(@RequestBody User user) {
        return "Created: " + user.getName();
    }
}

2. 启动并测试

bash
# 启动应用
mvn spring-boot:run

# 或直接运行 main 方法
# 默认端口:8080

# 测试
curl http://localhost:8080/api/hello
# 输出:Hello, Spring Boot!

📖 六、配置文件

1. application.yml(推荐)

yaml
# 服务器配置
server:
  port: 8080
  servlet:
    context-path: /api

# 应用配置
spring:
  application:
    name: demo
  
  # 数据源配置
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  # JPA 配置
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true
  
  # Redis 配置
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0

# 日志配置
logging:
  level:
    root: INFO
    com.example.demo: DEBUG
  file:
    name: logs/app.log

2. application.properties(等价)

properties
server.port=8080
server.servlet.context-path=/api

spring.application.name=demo
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=123456

logging.level.root=INFO
logging.level.com.example.demo=DEBUG

3. 自定义配置

yaml
# application.yml
app:
  name: My App
  version: 1.0.0
  author: Alice
  features:
    - feature1
    - feature2
java
// 读取配置
@Component
@ConfigurationProperties(prefix = "app")
@Data  // Lombok
public class AppConfig {
    private String name;
    private String version;
    private String author;
    private List<String> features;
}

// 使用
@RestController
public class ConfigController {
    
    @Autowired
    private AppConfig appConfig;
    
    @GetMapping("/config")
    public AppConfig getConfig() {
        return appConfig;
    }
}

📖 七、Profile 多环境配置

1. 创建多个配置文件

resources/
├── application.yml          # 公共配置
├── application-dev.yml      # 开发环境
├── application-test.yml     # 测试环境
└── application-prod.yml     # 生产环境

2. application.yml(公共)

yaml
spring:
  application:
    name: demo
  profiles:
    active: dev  # 激活开发环境

3. application-dev.yml(开发)

yaml
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo_dev
    username: root
    password: 123456

logging:
  level:
    root: DEBUG

4. application-prod.yml(生产)

yaml
server:
  port: 80

spring:
  datasource:
    url: jdbc:mysql://prod-server:3306/demo_prod
    username: prod_user
    password: ${DB_PASSWORD}  # 从环境变量读取

logging:
  level:
    root: WARN
  file:
    name: /var/log/app.log

5. 切换环境

bash
# 方式1:配置文件
spring.profiles.active=prod

# 方式2:启动参数
java -jar demo.jar --spring.profiles.active=prod

# 方式3:环境变量
export SPRING_PROFILES_ACTIVE=prod
java -jar demo.jar

# 方式4:IDEA 配置
Run Edit Configurations Active profiles: prod

📖 八、常用 Starter

Starter功能
spring-boot-starter-webWeb 开发(Spring MVC + Tomcat)
spring-boot-starter-data-jpaJPA 数据访问
spring-boot-starter-data-redisRedis 缓存
spring-boot-starter-securitySpring Security 安全
spring-boot-starter-validation参数校验
spring-boot-starter-test测试(JUnit + Mockito)
spring-boot-starter-actuator监控和管理
spring-boot-starter-mail邮件发送
spring-boot-starter-quartz定时任务
spring-boot-starter-websocketWebSocket

添加依赖示例

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

📖 九、自动配置原理

1. @SpringBootApplication 展开

java
@SpringBootConfiguration  // = @Configuration
@EnableAutoConfiguration  // 关键:启用自动配置
@ComponentScan           // 组件扫描
public @interface SpringBootApplication {
}

2. 自动配置流程

1. @EnableAutoConfiguration 导入 AutoConfigurationImportSelector
2. 读取 META-INF/spring.factories 文件
3. 加载所有自动配置类(xxxAutoConfiguration)
4. 根据 @Conditional 注解判断是否生效
5. 注册 Bean 到容器

3. 常见条件注解

java
@ConditionalOnClass         // 类路径存在某个类
@ConditionalOnMissingBean   // 容器中不存在某个 Bean
@ConditionalOnProperty      // 配置文件中存在某个属性
@ConditionalOnWebApplication // 是 Web 应用

// 示例
@Configuration
@ConditionalOnClass(DataSource.class)
public class MyAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        // 只有容器中没有 DataSource 时才创建
        return new HikariDataSource();
    }
}

📖 十、运行与打包

1. 开发模式运行

bash
# Maven
mvn spring-boot:run

# Gradle
gradle bootRun

# IDE
直接运行 main 方法

2. 打包

bash
# Maven 打包
mvn clean package

# 生成:target/demo-1.0.0.jar

3. 运行 JAR 包

bash
# 前台运行
java -jar demo-1.0.0.jar

# 后台运行
nohup java -jar demo-1.0.0.jar > app.log 2>&1 &

# 指定配置文件
java -jar demo-1.0.0.jar --spring.config.location=file:./config/application.yml

# 指定端口
java -jar demo-1.0.0.jar --server.port=9090

💡 最佳实践

  1. 使用 yml 格式配置(层次更清晰)
  2. 敏感信息用环境变量(不要硬编码密码)
  3. 合理使用 Profile(开发/测试/生产分离)
  4. 依赖版本交给 Spring Boot 管理(不要指定版本号)
  5. 使用 Lombok 减少模板代码

⚠️ 常见陷阱

1. 把 Spring Boot 理解成新框架

Spring Boot 不是替代 Spring,而是基于 Spring 的快速启动和自动配置体系。IoC、AOP、MVC、事务仍然是 Spring 的核心。

2. 手动指定大量依赖版本

Spring Boot Parent 和 BOM 已经管理了常见依赖版本。无理由覆盖版本可能导致兼容问题。

3. 配置文件里写死敏感信息

数据库密码、Token、AK/SK 不应该提交到仓库。生产环境用环境变量、配置中心或密钥管理系统。

4. Profile 混乱

开发、测试、生产配置必须清晰隔离。不要让生产环境加载 dev 配置。

5. 不了解自动配置条件

很多 Bean 是在 @ConditionalOnMissingBean@ConditionalOnClass 等条件满足时创建的。遇到“为什么这个 Bean 存在/不存在”时,要学会看自动配置报告。


🆚 Java vs C 对比

维度C 服务Spring Boot
启动入口main 手动初始化模块SpringApplication.run 启动容器
配置管理手写解析配置文件application.yml、Profile、配置绑定
依赖装配手动创建和传递指针IoC 自动装配
Web 集成手动接入 HTTP 框架starter 自动引入 Tomcat/Spring MVC
运维能力手动暴露健康检查Actuator 提供健康、指标、信息

Spring Boot 的价值是把企业应用的基础设施标准化,让开发者从重复搭框架中解放出来。


📝 练习预告

完成 练习/Ex57_SpringBoot_Basic.java

  1. 创建 Spring Boot 项目
  2. 实现 CRUD RESTful API
  3. 配置多数据源
  4. 多环境配置切换
  5. 自定义配置读取
  6. 综合:用户管理系统

🎓 下一步

  • 第58课:Spring Boot Web 开发 - RESTful API、参数校验、统一响应、异常处理