springboot2学习教程

1. Spring Boot 介绍

  • 什么是 Spring Boot
    • 简介和背景
    • Spring Boot 的优势
    • Spring Boot 与 Spring Framework 的关系
  • Spring Boot 的特性
    • 自动配置
    • 微服务支持
    • 嵌入式服务器
    • 生产就绪特性

2. 开发环境搭建

  • JDK 安装与配置
  • IDE 选择与配置
    • IntelliJ IDEA
    • Eclipse
  • 构建工具
    • Maven
    • Gradle

3. 创建第一个 Spring Boot 应用

使用 Spring Initializr 生成项目

Spring Initializr 是一个在线项目生成器,帮助开发者快速创建 Spring Boot 项目。

  1. 访问 Spring Initializr

  2. 配置项目

    • Project: 选择项目类型,一般选择 Maven ProjectGradle Project。Maven 是更常用的选择。
    • Language: 选择编程语言,通常选择 Java
    • Spring Boot Version: 选择所需的 Spring Boot 版本,一般选择最新稳定版本。
  3. 填写项目信息

    • Group: 输入项目的组织或公司名,例如 com.example
    • Artifact: 输入项目的名称,例如 demo
    • Name: 项目的名称,通常和 Artifact 相同。
    • Description: 项目的描述,例如 Demo project for Spring Boot
    • Package Name: 默认情况下,会自动生成,通常与 Group 和 Artifact 结合。
    • Packaging: 选择打包方式,通常选择 Jar
    • Java Version: 选择 Java 版本,建议使用 JDK 11 或更高版本。
  4. 选择依赖

    • 在下方的 Dependencies 部分,添加项目所需的依赖。常见的依赖包括:
      • Spring Web: 用于构建 RESTful 应用的基础库。
      • Spring Data JPA: 用于与数据库交互。
      • H2 Database: 嵌入式数据库,用于开发和测试。
      • Spring Boot DevTools: 提高开发效率的工具(可选)。
  5. 生成项目

    • 点击 “Generate” 按钮,下载生成的 ZIP 文件。
    • 解压缩该文件到本地目录。

项目结构解析

当您解压缩 Spring Initializr 生成的项目时,您将看到以下基本的项目结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
demo

├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── demo
│ │ │ └── DemoApplication.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── static
│ └── test
│ └── java
│ └── com
│ └── example
│ └── demo
│ └── DemoApplicationTests.java

├── pom.xml (对于 Maven 项目)或 build.gradle(对于 Gradle 项目)
└── README.md
  • src/main/java: 存放 Java 源代码的目录。

    • com/example/demo: 包结构,按照约定组织代码。
    • DemoApplication.java: Spring Boot 应用的入口,包含 main 方法。
  • src/main/resources: 存放资源文件的目录。

    • application.properties: Spring Boot 应用的配置文件。
    • static: 用于存放静态资源(如 HTML、CSS、JS 等)的目录。
  • src/test/java: 存放测试代码的目录。

  • pom.xml: Maven 项目的配置文件,定义了项目的依赖、插件等信息。

编写简单的 RESTful API

接下来,我们将编写一个简单的 RESTful API,该 API 提供对资源(如用户)的基本操作。

  1. 创建模型类(Model)

    • src/main/java/com/example/demo 下创建一个名为 User.java 的新文件:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.example.demo;

    public class User {
    private Long id;
    private String name;

    // 构造函数
    public User(Long id, String name) {
    this.id = id;
    this.name = name;
    }

    // Getter 和 Setter
    public Long getId() {
    return id;
    }

    public void setId(Long id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }
    }
  2. 创建控制器(Controller)

    • 创建一个名为 UserController.java 的新文件,用于处理用户请求:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.example.demo;

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

    import java.util.ArrayList;
    import java.util.List;

    @RestController
    @RequestMapping("/users")
    public class UserController {

    private List<User> userList = new ArrayList<>();

    @GetMapping
    public List<User> getAllUsers() {
    return userList;
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
    userList.add(user);
    return user;
    }
    }
    • 解释
      • @RestController:这是一个特殊的控制器,返回的对象会被自动序列化为 JSON。
      • @RequestMapping("/users"):定义基础 URL 路径为 /users
      • @GetMapping:处理 GET 请求,返回所有用户的信息。
      • @PostMapping:处理 POST 请求,接受用户数据并将其添加到列表中。
  3. 修改主应用类

    • DemoApplication.java 通常不需要修改,但是确保它存在并包含 main 方法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
    }
    }
  4. 运行应用程序

    • 在 IDE 中运行 DemoApplication 类,Spring Boot 应用将启动并监听默认端口 8080。
  5. 测试 RESTful API

    • 使用 Postman 或 curl 测试 API。
    • 获取所有用户
      • 发送 GET 请求到 http://localhost:8080/users,返回空列表。
    • 创建新用户
      • 发送 POST 请求到 http://localhost:8080/users,请求体为:
        1
        2
        3
        4
        {
        "id": 1,
        "name": "John Doe"
        }
      • 发送后再次 GET 请求以查看用户列表。

4. Spring Boot 核心特性

自动配置

Spring Boot 的自动配置 是其最重要的特性之一,旨在简化 Spring 应用的配置,减少开发者的手动配置工作。

Spring Boot 的自动配置原理
  1. 条件配置:

    • Spring Boot 使用了大量的“条件注解”来决定是否需要加载某些配置。例如,@ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty 等。
    • 这些注解根据当前应用的类路径、已经存在的 Bean、配置属性等条件来决定是否启用特定的配置。
  2. spring-boot-autoconfigure 模块:

    • Spring Boot 的自动配置主要通过 spring-boot-autoconfigure 模块实现。它包含许多自动配置类,每个类通常对应一个功能,例如 JDBC、Web、Security 等。
    • 自动配置类通常以 @Configuration 注解标记,通过 @EnableConfigurationProperties 加载配置属性。
  3. META-INF/spring.factories:

    • 在自动配置模块的 JAR 包中,META-INF/spring.factories 文件列出了所有的自动配置类。Spring Boot 在启动时会扫描这个文件,并加载相关的配置。
@EnableAutoConfiguration 注解的使用
  • @EnableAutoConfiguration 是一个非常重要的注解,通常在主类上使用。它告诉 Spring Boot 启用自动配置功能。
  • 该注解通常与 @SpringBootApplication 一起使用,后者实际上是组合了三个注解:
    • @Configuration: 表示该类是一个配置类。
    • @EnableAutoConfiguration: 启用自动配置。
    • @ComponentScan: 自动扫描当前包及其子包中的组件。
1
2
3
4
5
6
7
8
9
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);
}
}

应用配置

Spring Boot 支持多种方式进行配置,最常用的是 application.propertiesapplication.yml 文件。

application.propertiesapplication.yml
  1. application.properties:

    • Spring Boot 默认会在 src/main/resources 目录下寻找 application.properties 文件。
    • 常用配置示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      # 服务器端口
      server.port=8080

      # Spring 数据源配置
      spring.datasource.url=jdbc:mysql://localhost:3306/mydb
      spring.datasource.username=root
      spring.datasource.password=root

      # JPA 配置
      spring.jpa.hibernate.ddl-auto=update
      spring.jpa.show-sql=true

      # 日志级别
      logging.level.root=INFO
      logging.level.com.example.demo=DEBUG
  2. application.yml:

    • YAML 是一种更易读的配置格式,Spring Boot 也支持 application.yml
    • 常用配置示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      server:
      port: 8080

      spring:
      datasource:
      url: jdbc:mysql://localhost:3306/mydb
      username: root
      password: root
      jpa:
      hibernate:
      ddl-auto: update
      show-sql: true

      logging:
      level:
      root: INFO
      com.example.demo: DEBUG
  3. 选择配置文件:

    • Spring Boot 会优先加载 application.yml,如果同时存在 application.propertiesapplication.yml,则以 application.yml 为准。
自定义配置
  1. 创建自定义配置类:

    • 在 Spring Boot 中,可以创建自定义配置类来加载特定的配置属性。
    • 使用 @ConfigurationProperties 注解将配置属性映射到 Java 对象。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;

    @Component
    @ConfigurationProperties(prefix = "app")
    public class AppConfig {
    private String name;
    private String version;

    // Getter 和 Setter
    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getVersion() {
    return version;
    }

    public void setVersion(String version) {
    this.version = version;
    }
    }
  2. 在配置文件中定义属性:

    • 然后在 application.propertiesapplication.yml 文件中定义这些属性:
    1
    2
    app.name=My Application
    app.version=1.0.0
  3. 使用自定义配置:

    • 可以在需要的地方注入 AppConfig 类,并使用其属性:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class InfoController {

    @Autowired
    private AppConfig appConfig;

    @GetMapping("/info")
    public String getInfo() {
    return "App Name: " + appConfig.getName() + ", Version: " + appConfig.getVersion();
    }
    }

常用配置示例

以下是一些常见的 Spring Boot 配置项的详细说明:

  • 服务器配置:

    1
    2
    server.port=8080               # 设置服务器端口
    server.servlet.context-path=/api # 设置上下文路径
  • 数据源配置:

    1
    2
    3
    4
    spring.datasource.url=jdbc:mysql://localhost:3306/mydb  # 数据库连接 URL
    spring.datasource.username=root # 数据库用户名
    spring.datasource.password=root # 数据库密码
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # JDBC 驱动
  • JPA 和 Hibernate 配置:

    1
    2
    3
    spring.jpa.hibernate.ddl-auto=update  # 设置数据库架构自动更新
    spring.jpa.show-sql=true # 显示 SQL 查询
    spring.jpa.properties.hibernate.format_sql=true # 格式化 SQL
  • 日志配置:

    1
    2
    3
    logging.level.root=INFO                 # 设置根日志级别
    logging.level.com.example.demo=DEBUG # 设置特定包的日志级别
    logging.file.name=app.log # 输出日志文件名称
  • Spring Security 配置:

    1
    2
    spring.security.user.name=admin          # 默认用户名
    spring.security.user.password=admin123 # 默认密码

5. Spring Boot 中的组件

在 Spring Boot 应用中,通常会按照分层架构来组织代码,主要有控制器(Controller)、服务层(Service)和数据访问层(Repository)。以下是各个组件的详细讲解。

控制器(Controller)

控制器是处理 HTTP 请求的核心组件,负责接收请求并返回响应。

@RestController@Controller 的区别
  • @Controller:
    • 主要用于处理 Web 请求。它将返回的视图名称(通常是 JSP 或 Thymeleaf 模板)传递给视图解析器。
    • 适用于传统的基于视图的 Web 应用。
  • @RestController:
    • @RestController@Controller@ResponseBody 的组合注解。它表示该类中的每个方法的返回值将自动序列化成 JSON 或 XML 格式,直接返回给客户端。
    • 适用于 RESTful API 开发。

示例

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

@GetMapping("/users")
public String getUsers() {
return "Returning user list";
}
}
路由与请求映射(@GetMapping, @PostMapping 等)
  • Spring 提供了一系列注解用于处理不同类型的 HTTP 请求:
    • @GetMapping: 处理 GET 请求。
    • @PostMapping: 处理 POST 请求。
    • @PutMapping: 处理 PUT 请求。
    • @DeleteMapping: 处理 DELETE 请求。
    • @RequestMapping: 通用注解,可用于定义请求路径和请求方法。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

@GetMapping
public List<User> getAllUsers() {
// 返回用户列表
return new ArrayList<>();
}

@PostMapping
public User createUser(@RequestBody User user) {
// 创建用户
return user;
}
}

服务层(Service)

服务层主要负责业务逻辑的实现,通常会通过注入的方式连接控制器和数据访问层。

业务逻辑的实现

服务层通常包含多个方法,这些方法处理特定的业务逻辑,例如:

  • 数据验证
  • 调用数据访问层获取或存储数据
  • 处理业务规则等
使用 @Service 注解
  • @Service 注解用于标识服务层的组件。它的使用方式与 @Component 类似,可以让 Spring 容器识别该类并进行管理。

示例

1
2
3
4
5
6
7
8
9
10
import org.springframework.stereotype.Service;

@Service
public class UserService {

public User findUserById(Long id) {
// 业务逻辑,查找用户
return new User(id, "Sample User");
}
}

数据访问层(Repository)

数据访问层负责与数据库交互,通常使用 Spring Data JPA 来简化数据访问。

Spring Data JPA 集成

Spring Data JPA 是 Spring 的一个模块,提供了一种快速访问数据库的方法。通过定义接口,可以轻松实现 CRUD 操作,而无需编写复杂的 SQL 代码。

使用 @Repository 注解
  • @Repository 注解用于标识数据访问层的组件。它的主要作用是:
    • 将异常转换为 Spring 的数据访问异常。
    • 让 Spring 容器识别该类并进行管理。

示例

1
2
3
4
5
6
7
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByName(String name); // 自定义查询方法
}
JPQL 和原生 SQL 查询
  • JPQL (Java Persistence Query Language):
    • JPQL 是针对 JPA 的对象查询语言。它与 SQL 的不同之处在于,JPQL 是基于实体对象进行查询。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {

@PersistenceContext
private EntityManager entityManager;

public List<User> findAllUsers() {
TypedQuery<User> query = entityManager.createQuery("SELECT u FROM User u", User.class);
return query.getResultList();
}
}
  • 原生 SQL 查询:
    • 如果需要执行某些特定的 SQL 查询,可以使用 @Query 注解来编写原生 SQL 查询。

示例

1
2
3
4
5
6
7
8
9
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
User findUserByName(@Param("name") String name);
}

6. 数据库集成

在 Spring Boot 中,数据库集成是应用开发的重要组成部分。通过 Spring Data JPA,开发者可以方便地与数据库进行交互,同时支持多种数据库的配置与管理。以下是对数据库集成的详细讲解。

1. Spring Data JPA

JPA 概念与 Hibernate
  • JPA (Java Persistence API):

    • JPA 是 Java EE 的一种规范,定义了对象关系映射(ORM)的标准接口,使得 Java 对象能够与关系数据库之间进行映射和交互。
    • JPA 不直接实现数据库操作,而是通过实现 JPA 的 ORM 框架来实现,Hibernate 是其中最流行的实现之一。
  • Hibernate:

    • Hibernate 是一种开源的 ORM 框架,它实现了 JPA 规范,并提供了更丰富的功能,如缓存、懒加载、批量操作等。
    • Hibernate 允许开发者通过 Java 对象操作数据库,简化了数据库交互的复杂性。
通过 Spring Data JPA 进行数据库操作

Spring Data JPA 提供了一种快速访问数据库的方法,允许开发者通过定义接口来完成 CRUD 操作,而无需编写复杂的 SQL 代码。

  • 基本操作:
    • 创建一个接口继承 JpaRepository,可以直接使用 Spring Data JPA 提供的基本操作。

示例:

1
2
3
4
5
6
7
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email); // 自定义查询方法
}
  • CRUD 方法:
    • save(): 保存实体(插入或更新)。
    • findById(): 根据 ID 查找实体。
    • findAll(): 查找所有实体。
    • delete(): 删除实体。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public User createUser(User user) {
return userRepository.save(user);
}

public List<User> getAllUsers() {
return userRepository.findAll();
}

public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}

public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
实体类的定义与映射
  • 实体类:
    • 实体类是与数据库表直接映射的 Java 类,通常使用 @Entity 注解标记。实体类的属性对应数据库表的列。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import javax.persistence.*;

@Entity
@Table(name = "users") // 指定数据库表名
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键生成策略
private Long id;

private String name;

private String email;

// Getter 和 Setter
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}
  • 映射关系:
    • JPA 支持多种关系的映射,如一对一(@OneToOne)、一对多(@OneToMany)、多对一(@ManyToOne)、多对多(@ManyToMany)等。

示例(一对多关系):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
public class Post {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String title;

@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user; // 该帖子的作者

// Getter 和 Setter
}

2. 配置数据库连接

在 Spring Boot 应用中,可以通过配置文件来设置数据库连接。

H2、MySQL、PostgreSQL 的配置与使用
  • H2 数据库: 一个轻量级的关系数据库,适合开发和测试。
  • MySQL 数据库: 常用的开源关系数据库。
  • PostgreSQL 数据库: 高性能的开源对象关系数据库。

示例: application.properties 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# H2 数据库配置
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

# MySQL 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root

# PostgreSQL 数据库配置
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=postgres
数据源配置

除了基本的 URL、用户名和密码外,还可以配置连接池、连接数、超时等设置。

示例:

1
2
3
4
# 数据源连接池配置
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000

3. 数据库迁移

数据库迁移是指在数据库架构或数据变化时,管理和应用这些变化的过程。常用的工具有 Flyway 和 Liquibase。

使用 Flyway 进行数据库版本管理
  • Flyway: 一个开源的数据库迁移工具,通过 SQL 脚本或 Java 代码来管理数据库的版本。

配置 Flyway:

  1. 添加依赖:
1
2
3
4
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
  1. 创建迁移脚本:在 src/main/resources/db/migration 目录下创建 SQL 文件,命名格式为 V1__Initial.sql
1
2
3
4
5
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE
);
  1. 运行应用:Flyway 会自动检测并执行未应用的迁移脚本。
使用 Liquibase 进行数据库版本管理
  • Liquibase: 另一个开源的数据库版本控制工具,通过 XML、YAML、JSON 或 SQL 文件定义数据库变更。

配置 Liquibase:

  1. 添加依赖:
1
2
3
4
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
  1. 创建变更日志文件:在 src/main/resources 下创建 db.changelog-master.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">

<changeSet id="1" author="author">
<createTable tableName="users">
<column name="id" type="BIGINT">
<autoIncrement/>
<constraints primaryKey="true"/>
</column>
<column name="name" type="VARCHAR(100)"/>
<column name="email" type="VARCHAR(100)">
<constraints unique="true"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
  1. 运行应用:Liquibase 会在启动时自动执行变更日志。

7. 处理请求和响应

在 Spring Boot 应用中,处理请求和响应是核心功能之一。通过定义数据传输对象(DTO)、处理请求参数和路径变量、以及自定义响应结构和错误处理,可以构建灵活且高效的 RESTful API。以下是这一部分的详细讲解。

1. 数据传输对象(DTO)

概念:

  • DTO(Data Transfer Object)是用于传输数据的对象,通常用于在客户端和服务器之间传递数据。DTO 主要用于封装数据,以避免直接暴露实体对象给外部系统,从而提高安全性和灵活性。

用途:

  • 限制返回数据的字段(只返回客户端需要的字段)。
  • 避免冗余数据,减少网络传输负担。
  • 为不同操作(如创建、更新)定义不同的结构。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class UserDTO {
private String name;
private String email;

// Getter 和 Setter
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}

在控制器中的使用:

控制器方法可以接收和返回 DTO,而不是直接使用实体类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

@PostMapping
public UserDTO createUser(@RequestBody UserDTO userDTO) {
// 将 DTO 转换为实体类并保存
User user = new User();
user.setName(userDTO.getName());
user.setEmail(userDTO.getEmail());
userService.createUser(user);

return userDTO; // 返回 DTO
}
}

2. 请求参数和路径变量

请求参数:

  • 请求参数是通过 URL 查询字符串传递的参数,通常用来过滤或修改请求的行为。

示例:

1
2
3
4
5
@GetMapping
public List<UserDTO> getUsers(@RequestParam(required = false) String name) {
List<User> users = userService.findByName(name);
return users.stream().map(this::convertToDTO).collect(Collectors.toList());
}

路径变量:

  • 路径变量是 URL 路径的一部分,通常用于标识特定资源。

示例:

1
2
3
4
5
@GetMapping("/{id}")
public UserDTO getUserById(@PathVariable Long id) {
User user = userService.findUserById(id);
return convertToDTO(user);
}

3. 响应处理

自定义响应结构:

  • 可以通过创建一个统一的响应类来封装 API 的响应结构。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ApiResponse<T> {
private String message;
private T data;
private boolean success;

public ApiResponse(String message, T data, boolean success) {
this.message = message;
this.data = data;
this.success = success;
}

// Getter 和 Setter
public String getMessage() {
return message;
}

public T getData() {
return data;
}

public boolean isSuccess() {
return success;
}
}

在控制器中使用自定义响应:

1
2
3
4
5
6
7
8
9
@PostMapping
public ApiResponse<UserDTO> createUser(@RequestBody UserDTO userDTO) {
User user = new User();
user.setName(userDTO.getName());
user.setEmail(userDTO.getEmail());
userService.createUser(user);

return new ApiResponse<>("User created successfully", userDTO, true);
}

错误处理:

  • 在 RESTful API 中,处理错误响应是非常重要的。可以通过 @ControllerAdvice 来实现全局异常处理。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ApiResponse<String>> handleUserNotFound(UserNotFoundException ex) {
ApiResponse<String> response = new ApiResponse<>(ex.getMessage(), null, false);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<String>> handleGlobalException(Exception ex) {
ApiResponse<String> response = new ApiResponse<>("Internal Server Error", null, false);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
}

8. Spring Boot 的安全性

在现代应用中,安全性是至关重要的。Spring Boot 提供了强大的安全框架 Spring Security,允许开发者轻松实现认证和授权机制。通过 JSON Web Token(JWT),可以实现无状态的身份验证和安全性,这对微服务架构尤其重要。以下是对 Spring Boot 安全性以及 JWT 实现的详细讲解。

1. Spring Security 基础

认证与授权
  • 认证(Authentication): 验证用户的身份,确保用户是他们声称的那个人。常用的认证方式包括用户名和密码、OAuth、SAML 等。
  • 授权(Authorization): 确定用户是否有权访问特定资源或执行特定操作。授权通常基于角色或权限。
基本安全配置

要在 Spring Boot 应用中启用基本的安全性,可以使用 Spring Security 提供的机制。以下是基本的配置步骤。

依赖:

首先,在 pom.xml 中添加 Spring Security 依赖。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

配置类:

创建一个安全配置类,扩展 WebSecurityConfigurerAdapter,并重写 configure 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // 禁用 CSRF 保护(在 API 中不常用)
.authorizeRequests()
.antMatchers("/api/public/**").permitAll() // 允许所有人访问 /api/public/**
.anyRequest().authenticated() // 其他所有请求需要认证
.and()
.httpBasic(); // 使用基本认证
}
}

2. 使用 JWT 实现安全

JSON Web Token 原理
  • JWT: 是一种开放标准(RFC 7519),用于在网络应用环境之间以 JSON 对象安全地传递信息。JWT 可以包含用户的身份信息和权限信息,并且可以被签名和验证。

  • 结构: JWT 包含三个部分:

    1. 头部(Header): 通常包含令牌的类型(JWT)和所使用的签名算法。
    2. 有效载荷(Payload): 包含声明(claims),即用户信息(如用户 ID、角色等)。
    3. 签名(Signature): 通过头部和有效载荷及密钥进行加密生成的字符串,用于验证令牌的真实性。
Spring Boot 集成 JWT

下面是如何在 Spring Boot 中实现 JWT 的步骤。

依赖:

pom.xml 中添加 JWT 依赖。

1
2
3
4
5
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>

JWT 工具类:

创建一个 JWT 工具类,用于生成和验证 JWT。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {

private final String SECRET_KEY = "mysecretkey"; // 密钥
private final long EXPIRATION_TIME = 86400000; // 过期时间 1 天

// 生成 JWT
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, username);
}

private String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

// 验证 JWT
public boolean validateToken(String token, String username) {
final String extractedUsername = extractUsername(token);
return (extractedUsername.equals(username) && !isTokenExpired(token));
}

// 从 token 中提取用户名
public String extractUsername(String token) {
return extractAllClaims(token).getSubject();
}

// 检查 token 是否过期
private boolean isTokenExpired(String token) {
return extractAllClaims(token).getExpiration().before(new Date());
}

// 提取所有声明
private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
}

认证过滤器:

创建一个 JWT 过滤器,用于在请求中提取和验证 JWT。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtRequestFilter extends WebAuthenticationFilter {

@Autowired
private JwtUtil jwtUtil;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");

String username = null;
String jwt = null;

if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
}

if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// 这里可以根据用户名加载用户的权限,简化处理不做
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
chain.doFilter(request, response);
}
}

安全配置中添加过滤器:

在安全配置类中注册 JWT 过滤器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private JwtRequestFilter jwtRequestFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll() // 允许访问身份验证的端点
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 无状态

http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); // 之前添加过滤器
}
}

控制器:

创建一个身份验证控制器,允许用户登录并获取 JWT。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/auth")
public class AuthController {

@Autowired
private JwtUtil jwtUtil;

@PostMapping("/login")
public String login(@RequestBody AuthRequest authRequest) {
// 这里应该验证用户名和密码
// 由于示例省略,假设验证成功
String token = jwtUtil.generateToken(authRequest.getUsername());
return token; // 返回 JWT
}
}

用户认证请求 DTO:

创建一个简单的 DTO 用于接收认证请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class AuthRequest {
private String username;
private String password;

// Getter 和 Setter
public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

Demo 代码结构

  • src/main/java/com/example/demo
    • DemoApplication.java (主应用)
    • config
      • SecurityConfig.java (安全配置类)
    • controller
      • AuthController.java (身份验证控制器)
    • filter
      • JwtRequestFilter.java (JWT 过滤器)
    • util
      • JwtUtil.java (JWT 工具类)
    • dto
      • AuthRequest.java (请求 DTO)

9. Spring Boot 和前端的集成

在现代 Web 应用中,Spring Boot 通常用作后端服务,而前端框架(如 Angular、React 和 Vue.js)负责构建用户界面。以下是关于如何在 Spring Boot 中集成前端的详细讲解,包括使用 Thymeleaf 模板引擎以及 RESTful API 与前端框架的集成。

1. 使用 Thymeleaf

模板引擎的基本使用

Thymeleaf 是一个用于 Java 的现代服务器端模板引擎,专注于在 Web 和独立环境下的实现。它提供了自然模板支持,可以与 HTML 文件无缝结合,使得模板可以被浏览器直接渲染。

依赖:

pom.xml 中添加 Thymeleaf 依赖。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

基本配置:

Spring Boot 默认配置了 Thymeleaf。因此,我们只需创建 HTML 模板文件并将其放在 src/main/resources/templates 目录下。

示例模板 (src/main/resources/templates/index.html):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Example</title>
</head>
<body>
<h1 th:text="${title}">Welcome!</h1>
<ul>
<li th:each="user : ${users}">
<span th:text="${user.name}">User Name</span>
</li>
</ul>
</body>
</html>

控制器:

创建一个 Spring MVC 控制器来处理请求并返回视图名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;
import java.util.List;

@Controller
public class HomeController {

@GetMapping("/")
public String index(Model model) {
model.addAttribute("title", "Welcome to Thymeleaf");
List<User> users = Arrays.asList(new User("Alice"), new User("Bob"));
model.addAttribute("users", users);
return "index"; // 返回 index.html
}
}

用户类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class User {
private String name;

public User(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
动态内容生成

通过使用 Thymeleaf,您可以动态生成内容。例如,您可以根据用户输入或数据库内容生成列表、表格等。

动态表单示例:

1
2
3
4
<form action="#" th:action="@{/submit}" method="post">
<input type="text" name="username" placeholder="Enter your name" />
<button type="submit">Submit</button>
</form>

控制器处理表单提交:

1
2
3
4
5
@PostMapping("/submit")
public String submitForm(@RequestParam String username, Model model) {
model.addAttribute("message", "Hello, " + username);
return "result"; // 返回结果视图
}

2. RESTful API 和前端框架

现代前端框架(如 Angular、React 和 Vue.js)通常通过 RESTful API 与后端进行通信。Spring Boot 提供了便捷的方式来构建 RESTful API。

创建 RESTful API

创建一个基本的 RESTful API 控制器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserApiController {

@GetMapping
public List<User> getUsers() {
return Arrays.asList(new User("Alice"), new User("Bob"));
}

@PostMapping
public User createUser(@RequestBody User user) {
// 在此处可以将用户信息保存到数据库
return user; // 返回创建的用户
}
}
集成前端框架
  1. Angular 集成:

    • 使用 Angular CLI 创建一个 Angular 项目。
    • 在 Angular 服务中使用 HttpClient 发送请求。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { User } from './user.model';

    @Injectable({
    providedIn: 'root'
    })
    export class UserService {
    private apiUrl = 'http://localhost:8080/api/users';

    constructor(private http: HttpClient) { }

    getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.apiUrl);
    }

    createUser(user: User): Observable<User> {
    return this.http.post<User>(this.apiUrl, user);
    }
    }
    • 在组件中调用服务方法。
  2. React 集成:

    • 使用 create-react-app 创建一个 React 项目。
    • 使用 axiosfetch 发送请求。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import React, { useEffect, useState } from 'react';
    import axios from 'axios';

    const App = () => {
    const [users, setUsers] = useState([]);

    useEffect(() => {
    const fetchUsers = async () => {
    const response = await axios.get('http://localhost:8080/api/users');
    setUsers(response.data);
    };
    fetchUsers();
    }, []);

    return (
    <div>
    <h1>User List</h1>
    <ul>
    {users.map(user => (
    <li key={user.name}>{user.name}</li>
    ))}
    </ul>
    </div>
    );
    };

    export default App;
  3. Vue.js 集成:

    • 使用 Vue CLI 创建一个 Vue 项目。
    • 使用 axios 发送请求。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <template>
    <div>
    <h1>User List</h1>
    <ul>
    <li v-for="user in users" :key="user.name">{{ user.name }}</li>
    </ul>
    </div>
    </template>

    <script>
    import axios from 'axios';

    export default {
    data() {
    return {
    users: []
    };
    },
    mounted() {
    axios.get('http://localhost:8080/api/users')
    .then(response => {
    this.users = response.data;
    });
    }
    };
    </script>

10. Spring Boot 测试

  • 测试的基本概念
  • 单元测试与集成测试
  • 使用 JUnit 和 Mockito
  • Spring Boot 的测试支持
    • @SpringBootTest
    • MockMvc

11. Spring Boot 的性能优化

  • Profiling 和监控
  • 连接池配置
  • Caffeine 和 Redis 缓存集成

12. Spring Boot 的部署

在开发完 Spring Boot 应用后,部署是将应用发布到生产环境的重要步骤。以下是关于如何打包和运行 Spring Boot 应用、部署到云环境、以及使用 Docker 进行容器化的详细讲解。

1. 打包和运行

JAR 和 WAR 包的打包

Spring Boot 可以将应用打包为可执行的 JAR 或 WAR 文件。

JAR 包的打包:

pom.xml 中,Spring Boot 默认配置为打包 JAR 文件。您可以使用以下命令打包应用:

1
mvn clean package

打包完成后,您可以在 target 目录中找到生成的 JAR 文件。使用以下命令运行 JAR 文件:

1
java -jar target/your-application.jar

WAR 包的打包:

如果您希望将应用打包为 WAR 文件(通常用于传统的 Servlet 容器如 Tomcat),需要在 pom.xml 中进行一些配置。首先,确保您的 SpringBootApplication 类扩展自 SpringBootServletInitializer

1
2
3
4
5
6
7
8
9
10
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

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

pom.xml 中,修改 <packaging> 元素:

1
<packaging>war</packaging>

然后,可以使用相同的命令打包应用,生成的 WAR 文件将位于 target 目录中。您可以将这个 WAR 文件部署到支持 Servlet 的 Web 服务器(如 Tomcat)。

2. 部署到云环境

AWS

在 AWS 上部署 Spring Boot 应用的常见方法是通过 Elastic Beanstalk 或 EC2。

使用 Elastic Beanstalk:

  1. 确保您已安装 AWS CLI,并配置您的 AWS 凭证。
  2. 使用 Elastic Beanstalk CLI 创建应用程序。
1
2
eb init
eb create your-environment-name
  1. 部署您的应用:
1
eb deploy
  1. 访问您的应用 URL。
Azure

在 Azure 上,您可以使用 Azure App Service 来部署 Spring Boot 应用。

  1. 创建 Azure App Service 实例。
  2. 使用 Azure CLI 登录并设置应用服务。
1
2
3
az login
az appservice plan create --name your-app-service-plan --resource-group your-resource-group --sku B1 --is-linux
az webapp create --resource-group your-resource-group --plan your-app-service-plan --name your-app-name --runtime "JAVA|11-java11"
  1. 部署应用:
1
az webapp deploy --resource-group your-resource-group --name your-app-name --src-path target/your-application.jar
Heroku

在 Heroku 上部署 Spring Boot 应用也非常简单。

  1. 安装 Heroku CLI,然后登录:
1
heroku login
  1. 创建新的 Heroku 应用并设置 buildpack:
1
2
heroku create your-app-name
heroku buildpacks:set heroku/java
  1. 部署 JAR 文件:
1
heroku deploy:jar target/your-application.jar
  1. 访问您的应用 URL。

3. Docker 与 Spring Boot

创建 Dockerfile

Docker 是一个流行的容器化技术,您可以将 Spring Boot 应用容器化,以便于部署和管理。

在项目根目录下创建一个 Dockerfile,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用官方 Java 运行时作为基础镜像
FROM openjdk:11-jdk-slim

# 设定工作目录
WORKDIR /app

# 将 JAR 文件复制到容器中
COPY target/your-application.jar app.jar

# 暴露应用的端口
EXPOSE 8080

# 运行应用
ENTRYPOINT ["java", "-jar", "app.jar"]
容器化 Spring Boot 应用
  1. 构建 Docker 镜像:
1
docker build -t your-image-name .
  1. 运行 Docker 容器:
1
docker run -p 8080:8080 your-image-name
  1. 访问您的应用:

通过 http://localhost:8080 访问应用。

使用 Docker Compose(可选)

如果您的应用依赖于数据库或其他服务,可以使用 Docker Compose 管理多容器应用。创建一个 docker-compose.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: '3'
services:
app:
image: your-image-name
build: .
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/your_database
SPRING_DATASOURCE_USERNAME: your_username
SPRING_DATASOURCE_PASSWORD: your_password

db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: your_password
MYSQL_DATABASE: your_database

然后,使用以下命令启动所有服务:

1
docker-compose up

13. 微服务架构

  • 微服务基础知识
  • 使用 Spring Cloud
    • 服务注册与发现(Eureka)
    • API 网关(Zuul 或 Spring Cloud Gateway)
    • 配置管理(Spring Cloud Config)

14. 实战项目

  • 综合实战项目
    • 设计与实现一个完整的应用(例如,电商平台、博客系统等)
  • 项目的优化与重构

15. 学习资源与社区

  • 官方文档
  • 书籍推荐
  • 在线课程与视频
  • 开源项目与 GitHub

总结

学习 Spring Boot 2 是一个循序渐进的过程,建议根据学习大纲逐步深入,实践中不断巩固所学知识。通过创建简单的项目、逐步增加复杂度,并结合实际应用场景,能够更好地掌握 Spring Boot 的核心理念和实践技巧。