> 技术文档 > Spring Boot 全方位指南:从项目初始化到分层架构搭建

Spring Boot 全方位指南:从项目初始化到分层架构搭建


Spring Boot 全方位指南:从项目初始化到分层架构搭建

本教程旨在引导 Java 开发者,特别是 Spring Boot 的初学者,从零开始创建一个结构清晰、功能完备的后端项目。

我们将从项目初始化开始,详细讲解每一项依赖的作用,然后配置数据库,并最终搭建起经典的 MVC(Model-View-Controller)分层架构。

1. 依赖讲解

在创建项目之前,理解核心依赖的作用至关重要。它们是构建项目的基础。

通用依赖

  • Spring Web: 这是构建 Web 应用的核心模块,包括传统的 Spring MVC 和 RESTful API。它内置了 Tomcat 服务器,使我们无需额外配置 Web 服务器就能运行项目。
  • Lombok: 一个非常实用的 Java 库,可以通过注解自动生成构造函数、Getter/Setter、toString() 等模板代码,极大地简化了实体类和数据传输对象的编写。
  • Spring Boot DevTools: 开发阶段的辅助工具。它提供了热部署功能,当你修改代码后,应用会自动重新启动,无需手动操作,从而显著提升开发效率。
  • Springdoc OpenAPI: 用于根据代码自动生成 OpenAPI 3.0 格式的 API 文档。它与 Swagger UI 集成,提供了一个美观且可交互的 API 测试界面。

数据库相关依赖

根据你选择的数据库,需要引入不同的依赖:

  • MongoDB:
    • Spring Data MongoDB: 提供了在 Spring 应用中与 MongoDB 数据库交互的便捷支持,包括对象-文档映射 (ODM) 和 Repository 抽象。
  • MySQL:
    • Spring Data JPA: Java Persistence API (JPA) 是 Java EE 的标准规范,用于对象关系映射 (ORM)。Spring Data JPA 在其基础上提供了更高层次的抽象,简化了数据访问层的开发。
    • MySQL Driver: 这是 MySQL 数据库的 JDBC 驱动,是 Java 应用连接 MySQL 数据库的桥梁。

2. 初始化项目步骤详细

我们将使用 Spring Initializr 这个官方工具来生成项目骨架。

请按照以下步骤进行配置:

  • Project: 选择 Maven。Maven 是一个强大的项目管理和构建工具。

  • Language: 选择 Java

  • Spring Boot: 选择一个稳定且被广泛推荐的版本,例如 3.5.3 或其他 3.x.x 系列的非快照版本。

  • Project Metadata:

    • Group: com.example (通常是你的公司或组织域名倒写)
    • Artifact: my-spring-project (项目名称)
    • Name: my-spring-project (同上)
    • Description: Demo project for Spring Boot (项目描述)
    • Package name: com.example.myspringproject (项目的基础包名)
  • Packaging: 选择 Jar。这是现代微服务架构中最常见的打包方式,项目会作为一个独立的可执行文件运行。

  • Java: 选择一个长期支持 (LTS) 版本,如 1721

  • Dependencies: 在页面右侧,点击 “ADD DEPENDENCIES…” 按钮,然后搜索并添加以下依赖:

    • Spring Web
    • Lombok
    • Spring Boot DevTools
    • 根据你的数据库选择:
      • MongoDB 用户: 添加 Spring Data MongoDB
      • MySQL 用户: 添加 Spring Data JPAMySQL Driver

完成以上配置后,点击 “GENERATE” 按钮下载项目压缩包,然后在你的 IDE (如 IntelliJ IDEA 或 Eclipse 或 VS Code) 中导入该 Maven 项目。

附录:在 Visual Studio Code 中打开和运行项目

对于 VS Code 用户,请遵循以下步骤来设置和运行你的 Spring Boot 项目。

  1. 安装必备扩展:
    在开始之前,请确保你已经在 VS Code 中安装了 Java 开发的必备扩展。在扩展市场中搜索并安装以下扩展包,它提供了对 Java 开发的全面支持:

    • Extension Pack for Java (来自 Microsoft)
  2. 打开项目:
    将从 Spring Initializr 下载的压缩包解压。然后,在 VS Code 中,通过菜单栏的 文件 (File) > 打开文件夹... (Open Folder...),选择刚刚解压的项目根目录。

  3. 项目加载:
    VS Code 会自动识别这是一个基于 Maven 的 Java 项目。右下角会弹出提示,询问你是否信任此工作区,请选择“是”。之后,Java 扩展会自动开始下载项目所需的依赖项 (Dependencies)。你可以在左侧边栏的 JAVA PROJECTS 视图中看到项目的结构和依赖加载进度。

  4. 运行项目:
    项目依赖加载完毕后,请在文件资源管理器中找到 src/main/java/com/example/myspringproject/MySpringProjectApplication.java 文件。你有多种方式启动它:

    • 在编辑器中运行: 打开该文件。你会发现在 main 方法的上方,VS Code 会显示 Run | Debug 的可点击选项。同时,编辑器的右上角也会出现一个播放 (▶️) 按钮。点击其中任意一个都可以启动应用。
    • 在文件浏览器中运行: 在左侧的文件资源管理器中,直接右键点击 MySpringProjectApplication.java 文件,在弹出的上下文菜单中选择 运行 Java (Run Java)

3. 项目转化为基于 Java 8 的修改方法(按需)

虽然推荐使用 Java 17 或 21,但如果你因旧有环境限制必须使用 Java 8,可以手动修改 pom.xml 文件。

打开项目根目录下的 pom.xml 文件,找到 标签,将其中的 修改为 1.8

<properties> <java.version>1.8</java.version></properties>

同时,你需要确保你的 Spring Boot 版本与 Java 8 兼容。Spring Boot 3.x 及以上版本要求 Java 17 或更高,因此你需要选择一个 2.x.x 的版本,例如 2.7.18。这通常在 标签中修改:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/></parent>

重要:jakarta vs javax 命名空间变更

这是一个非常关键的技术点。从 Spring Boot 3.0 开始,Spring 框架迁移到了 Jakarta EE 9 规范,最直观的变化就是 Java EE API 的包名从 javax.* 变成了 jakarta.*

  • Spring Boot 3.x (Java 17+): 使用 jakarta.persistence.*
  • Spring Boot 2.x (Java 8/11): 使用 javax.persistence.*

因此,如果你按照本节步骤降级到了 Spring Boot 2.x,在后续编写 JPA 实体类(如 User 实体)时,必须手动将所有 import jakarta.persistence.* 修改为 import javax.persistence.*,否则项目将无法编译。

4. 需要手动添加的依赖

Springdoc OpenAPI 并非总是在所有 Spring Initializr 版本中都作为默认选项提供。如果初始化时未能添加,你需要手动将其添加到 pom.xml 区域。

重要提示: springdoc-openapi 的版本与 Spring Boot 的版本是紧密相关的。请根据你的 Spring Boot 版本选择正确的依赖。

场景一:Spring Boot 3.x (推荐)

如果你使用的是 Spring Boot 3.x (例如 3.5.3),你需要添加 v2.x.x 版本的 springdoc-openapi

<dependencies>   <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.5.0</version> </dependency></dependencies>

注意: 请检查并使用最新的 2.x 稳定版本号。

场景二:Spring Boot 2.x (兼容旧版 Java 8)

如果你根据前面的步骤降级到了 Spring Boot 2.x (例如 2.7.18),则必须使用 v1.x.x 版本的 springdoc-openapi,并且 artifactId 也不同。

<dependencies>   <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.8.0</version> </dependency></dependencies>

注意: 请检查并使用最新的 1.x 稳定版本号。

5. 数据库支持

接下来,我们将在 src/main/resources/ 目录下的配置文件中添加数据库连接信息。你可以选择 application.propertiesapplication.yml 格式。yml 格式层级更清晰,是目前更主流的选择。

情况一:集成 MongoDB

MongoDB 的 Windows 下安装方法可见 这篇文章

确保你的 pom.xml 文件中包含 spring-boot-starter-data-mongodb 依赖。

application.properties 格式配置:

# MongoDB Configuration# 使用 URI 方式连接,包含了地址、端口、数据库名等信息spring.data.mongodb.uri=mongodb://localhost:27017/mydatabase# 如果你的 MongoDB 设置了用户名和密码,可以使用以下格式# spring.data.mongodb.uri=mongodb://user:password@localhost:27017/mydatabase# 或者分别指定主机、端口和数据库名# spring.data.mongodb.host=localhost# spring.data.mongodb.port=27017# spring.data.mongodb.database=mydatabase# spring.data.mongodb.username=your_username# spring.data.mongodb.password=your_password# spring.data.mongodb.authentication-database=admin # 指定认证数据库

application.yml 格式配置:

spring: data: mongodb: uri: mongodb://localhost:27017/mydatabase # 或者分别指定主机、端口和数据库名 # host: localhost # port: 27017 # database: mydatabase # username: your_username # password: your_password # authentication-database: admin # 指定认证数据库

authentication-database 配置详解

authentication-database 是一个非常重要的配置项,尤其是在需要认证的生产环境中。

  • 作用: 它用于指定对哪个数据库进行用户身份验证。当你提供的 usernamepassword 不是在当前连接的数据库 (mydatabase) 中创建的,而是在另一个特定的数据库(通常是 admin 库)中创建时,就必须设置此项。
  • 常见场景: 在 MongoDB 中,管理员通常会在 admin 数据库中创建用户,并授予该用户访问其他一个或多个数据库的权限。在这种情况下,即使你的应用程序操作的是 mydatabase,认证过程也必须在 admin 数据库中进行。
  • 如何配置: 如果你使用独立的配置项(而非 URI),请添加 spring.data.mongodb.authentication-database=admin。如果使用 URI,可以在连接字符串中添加 authSource 参数,例如:mongodb://user:password@localhost:27017/mydatabase?authSource=admin

情况二:集成 MySQL

确保你的 pom.xml 文件中包含 spring-boot-starter-data-jpamysql-connector-j 依赖。

application.properties 格式配置:

# MySQL Datasource Configurationspring.datasource.url=jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=truespring.datasource.username=rootspring.datasource.password=your_password# JPA (Hibernate) Configuration# ddl-auto:# none: 不做任何操作# validate: 校验 schema,如果实体与表结构不匹配则报错# update: 启动时更新 schema,使其与实体匹配# create: 每次启动时都删除并重新创建 schema# create-drop: 启动时创建,关闭时删除spring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=true # 在控制台打印执行的 SQL 语句,方便调试

application.yml 格式配置:

spring: datasource: url: jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true username: root password: your_password jpa: hibernate: ddl-auto: update show-sql: true

6. 修改服务端口号

Spring Boot 内嵌的 Web 服务器(如 Tomcat)默认使用 8080 端口。如果该端口被占用或你希望使用其他端口,可以通过修改配置文件轻松实现。此项配置与数据库配置一样,都位于 src/main/resources/ 目录下。

application.properties 格式配置:

# Server Configurationserver.port=8090

application.yml 格式配置:

server: port: 8090

提示: 修改端口后,所有访问地址(包括 API 文档地址)都需要使用新的端口号,例如 http://localhost:8090/swagger-ui.html

7. 搭建基础分层结构

现在,我们开始搭建项目的核心代码结构。一个良好的分层结构可以使代码更清晰、更易于维护。我们遵循 Entity -> Repository -> Service -> Controller 的经典模式。

首先,在 src/main/java/com/example/myspringproject/ 目录下创建以下四个包:

  • entity (或 model): 存放数据实体类。
  • repository: 存放数据访问接口。
  • service: 存放业务逻辑代码。
  • controller: 存放 API 接口。

在 VS Code 中创建包 (文件夹):

  1. 在左侧的 文件夹 (FOLDERS) 视图中,找到并展开 src/main/java/com/example/myspringproject 目录。
  2. 右键点击 myspringproject 文件夹。
  3. 在弹出的菜单中选择 新建文件夹 (New Folder)
  4. 输入第一个包名,例如 entity,然后按 Enter。
  5. 重复以上步骤,创建 repositoryservicecontroller 这三个包。

创建实体层 (Entity/Model)

实体是与数据库表或文档结构对应的 Java 对象。

MongoDB 场景:

创建一个 User 类,使用 @Document 注解表示它对应 MongoDB 中的一个集合。

src/main/java/com/example/myspringproject/entity/User.java

package com.example.myspringproject.entity;import lombok.Data;import org.springframework.data.annotation.Id;import org.springframework.data.mongodb.core.mapping.Document;@Data // Lombok 注解,自动生成 Getter, Setter, toString() 等方法@Document(collection = \"users\") // 映射到 MongoDB 中的 \"users\" 集合public class User { @Id private String id; // MongoDB 的主键通常是字符串类型 private String username; private String email;}

MySQL 场景:

创建一个 User 类,使用 @Entity 注解表示它是一个 JPA 实体。

src/main/java/com/example/myspringproject/entity/User.java

package com.example.myspringproject.entity;// 重要提示:// 如果你使用的是 Spring Boot 2.x (对应 Java 8),// 需要将下面的 \'jakarta.persistence\' 全部替换为 \'javax.persistence\'import jakarta.persistence.*;import lombok.Data;@Data // Lombok 注解@Entity // 声明这是一个 JPA 实体@Table(name = \"users\") // 映射到数据库中的 \"users\" 表public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增策略 private Long id; // MySQL 的主键通常是 Long 类型 private String username; private String email;}

创建数据访问层 (Repository)

Repository 层负责与数据库进行直接交互,提供基础的增删改查功能。

MongoDB 场景:

创建一个 UserRepository 接口,继承 MongoRepository

src/main/java/com/example/myspringproject/repository/UserRepository.java

package com.example.myspringproject.repository;import com.example.myspringproject.entity.User;import org.springframework.data.mongodb.repository.MongoRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface UserRepository extends MongoRepository<User, String> { // Spring Data MongoDB 会自动实现基础的 CRUD 方法 // 你也可以在这里定义符合规范的自定义查询方法,例如: // Optional findByUsername(String username);}

MySQL 场景:

创建一个 UserRepository 接口,继承 JpaRepository

src/main/java/com/example/myspringproject/repository/UserRepository.java

package com.example.myspringproject.repository;import com.example.myspringproject.entity.User;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;@Repository // 声明这是一个 Spring 管理的 Beanpublic interface UserRepository extends JpaRepository<User, Long> { // JpaRepository 已经提供了丰富的 CRUD 操作 // 和分页、排序等功能。}

创建业务逻辑层 (Service)

Service 层封装了核心的业务逻辑,它调用 Repository 层来持久化数据。

Service 的代码对于 MongoDB 和 MySQL 几乎一样,唯一区别在于 findUserById 方法的参数类型,这取决于 User 实体的主键类型 (String for MongoDB, Long for MySQL)。

下面以 MongoDB 为例展示 UserService 的代码。对于 MySQL,只需将 findUserById 方法的参数 id 类型从 String 改为 Long 即可。

src/main/java/com/example/myspringproject/service/UserService.java

package com.example.myspringproject.service;import com.example.myspringproject.entity.User;import com.example.myspringproject.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Service // 声明这是一个业务逻辑组件public class UserService { private final UserRepository userRepository; // 推荐使用构造函数注入,确保依赖的不可变性 @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } /** * 创建一个新用户 * @param user 用户实体 * @return 保存后的用户实体 */ public User createUser(User user) { return userRepository.save(user); } /** * 根据 ID 查找用户 * @param id 用户 ID (MongoDB 使用 String, MySQL 使用 Long) * @return 用户实体,如果不存在则返回 null */ public User findUserById(String id) { // MySQL 用户请将 String id 改为 Long id return userRepository.findById(id).orElse(null); }}

创建表现层 (Controller)

Controller 层负责接收 HTTP 请求,调用 Service 层处理业务,并返回 HTTP 响应。

Controller 的代码在 MongoDB 和 MySQL 两种场景下几乎完全相同。唯一的区别在于 getUserById 方法中 ID 的类型。

下面以 MongoDB 场景为例,其中用户 ID 为 String 类型。如果你使用 MySQL,只需将 getUserById 方法的参数 @PathVariable String id 修改为 @PathVariable Long id 即可,其他部分完全相同

src/main/java/com/example/myspringproject/controller/UserController.java

package com.example.myspringproject.controller;import com.example.myspringproject.entity.User;import com.example.myspringproject.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;@RestController // 结合了 @Controller 和 @ResponseBody,返回 JSON 数据@RequestMapping(\"/api/users\") // 定义此控制器下所有 API 的基础路径public class UserController { private final UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } /** * 创建用户的 API 端点 * @param user 从请求体中接收的 User 对象 * @return 创建的用户信息 */ @PostMapping public User createUser(@RequestBody User user) { return userService.createUser(user); } /** * 根据 ID 查询用户的 API 端点 * @param id 从路径中获取的用户 ID (String) * @return 包含用户信息的 ResponseEntity */ @GetMapping(\"/{id}\") public ResponseEntity<User> getUserById(@PathVariable String id) { User user = userService.findUserById(id); if (user != null) { return ResponseEntity.ok(user); // 返回 200 OK 和用户信息 } else { return ResponseEntity.notFound().build(); // 返回 404 Not Found } }}

8. 生成并访问 API 文档

现在,你的项目已经准备就绪。

  1. 运行项目:

    • 在 IDE 中,找到主应用程序类(MySpringProjectApplication.java),右键点击并选择 “Run”。
    • 或者在项目根目录下打开终端,执行命令 mvn spring-boot:run
  2. 访问 API 文档:

    • 项目成功启动后,打开浏览器并访问:http://localhost:8080/swagger-ui.html
    • 你将看到一个由 Springdoc 生成的交互式 API 页面。
  3. 测试 API:

    • 在 Swagger UI 页面,你可以看到 POST /api/usersGET /api/users/{id} 两个端点。
    • 展开 POST 端点,点击 “Try it out”,在请求体中输入 JSON 数据(如 {\"username\": \"Alice\", \"email\": \"alice@example.com\"}),然后点击 “Execute”。
    • 复制响应中返回的 ID,然后使用 GET 端点进行查询。

至此,你已经成功地创建了一个结构完整、包含数据库集成和 API 文档的 Spring Boot 后端项目。以此为基础,你可以继续扩展更复杂的业务功能。