Skip to content
第 5 章 ⏱ 12 分钟阅读

第 5 章:搭建脚手架 ​

学习目标 ​

  • 从零创建 Spring Boot 多模块 Maven 项目
  • 配置 application.yml 多环境
  • 启动后端并访问 Swagger UI

一、创建多模块项目 ​

用 IDEA 创建一个空的 Maven 父工程,然后手动添加子模块。

步骤:

  1. File → New → Project → Maven 不勾 archetype
  2. 命名: taskflow-parent,GroupId com.taskflow
  3. 删除自动生成的 src 目录(父工程不需要)

目录结构:

taskflow-parent/
├── pom.xml                    # 父 POM(只做依赖和版本管理)
├── taskflow-common/
│   ├── pom.xml
│   └── src/main/java/
├── taskflow-system/
│   ├── pom.xml
│   └── src/main/java/
└── taskflow-application/      # 启动模块
    ├── pom.xml
    └── src/main/
        ├── java/
        └── resources/application.yml

每个子模块手动建 pom.xml,然后在父 pom.xml 的 <modules> 注册。

二、父 POM ​

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>

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

    <groupId>com.taskflow</groupId>
    <artifactId>taskflow-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>taskflow-common</module>
        <module>taskflow-system</module>
        <module>taskflow-application</module>
    </modules>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <mybatis-plus.version>3.5.5</mybatis-plus.version>
        <hutool.version>5.8.25</hutool.version>
        <jjwt.version>0.12.5</jjwt.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.taskflow</groupId>
                <artifactId>taskflow-common</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.taskflow</groupId>
                <artifactId>taskflow-system</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt-api</artifactId>
                <version>${jjwt.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

⚠️ 坑 1:子模块一定要显式声明父工程 (<parent><relativePath/></parent>)。没有 <relativePath/> 会去 Maven 仓库找父 POM,第一次开发根本找不到,导致 Non-resolvable parent POM 错误。

三、子模块 POM ​

3.1 taskflow-common ​

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taskflow</groupId>
        <artifactId>taskflow-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>taskflow-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

3.2 taskflow-system ​

xml
<dependencies>
    <!-- 依赖 common -->
    <dependency>
        <groupId>com.taskflow</groupId>
        <artifactId>taskflow-common</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

3.3 taskflow-application ​

xml
<dependencies>
    <dependency>
        <groupId>com.taskflow</groupId>
        <artifactId>taskflow-common</artifactId>
    </dependency>
    <dependency>
        <groupId>com.taskflow</groupId>
        <artifactId>taskflow-system</artifactId>
    </dependency>

    <!-- 因为是启动模块,加 spring-boot-maven-plugin -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

四、application.yml ​

主配置文件 + 多环境配置。

yaml
# application.yml (主配置)
spring:
  profiles:
    active: dev
  application:
    name: taskflow
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss

server:
  port: 8080
  shutdown: graceful     # 关闭时优雅停机
yaml
# application-dev.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/taskflow?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
    username: root
    password: root123
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5

  data:
    redis:
      host: localhost
      port: 6379
      password:
      database: 0

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  type-aliases-package: com.taskflow.**.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    banner: false
    db-config:
      id-type: assign_id          # 雪花算法生成 ID
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
      update-strategy: not_null    # 只更新非空字段

jwt:
  secret: taskflow-secret-key-must-be-at-least-32-bytes
  access-expire: 7200         # 2 小时
  refresh-expire: 2592000     # 30 天

logging:
  level:
    root: INFO
    com.taskflow: DEBUG

⚠️ 坑 2:update-strategy: not_null 是 MyBatis Plus 的关键配置。它的作用是:更新时只 set 非 null 字段。否则你 updateById(user) 时,没赋值的字段会被改成 null,导致数据被误清空。

五、启动类 ​

java
package com.taskflow;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(scanBasePackages = "com.taskflow")
@MapperScan("com.taskflow.**.mapper")
@EnableCaching                    // 开启缓存(@Cacheable 生效)
@EnableAsync                      // 开启异步(@Async 生效)
@EnableTransactionManagement      // 开启事务(@Transactional 生效)
public class TaskflowApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskflowApplication.class, args);
        System.out.println("\nTaskFlow 启动成功:http://localhost:8080\n");
    }
}

六、Hello World 接口 ​

先写个测试接口验证项目能跑通:

java
@RestController
@RequestMapping("/api/test")
public class TestController {

    @GetMapping("/hello")
    public Result<String> hello() {
        return Result.ok("Hello TaskFlow");
    }
}

启动应用,访问 http://localhost:8080/api/test/hello:

json
{
    "code": 200,
    "message": "操作成功",
    "data": "Hello TaskFlow"
}

返回了 Result 包装的 JSON,说明统一响应生效了。

七、引入 Swagger ​

xml
<!-- pom.xml 加这个依赖 -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>
yaml
# application.yml
springdoc:
  api-docs:
    path: /v3/api-docs
  swagger-ui:
    path: /swagger-ui.html
    operations-sorter: alpha
    tags-sorter: alpha

访问 http://localhost:8080/swagger-ui.html 即可看到 API 文档。

⚠️ 坑 3:生产环境必须关掉 Swagger!否则所有人都能看你的接口,等于把数据库结构白送出去。通过 application-prod.yml 关闭:

yaml
# application-prod.yml
springdoc:
  api-docs:
    enabled: false
  swagger-ui:
    enabled: false

八、Docker Compose 一键起依赖 ​

开发时不要本机装 MySQL/Redis,直接用 Docker:

yaml
# docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: taskflow-mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: taskflow
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
      - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    networks:
      - taskflow-net

  redis:
    image: redis:7-alpine
    container_name: taskflow-redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - taskflow-net

volumes:
  mysql-data:
  redis-data:

networks:
  taskflow-net:
    driver: bridge
bash
docker compose up -d

九、本章小结 ​

要点关键
多模块parent / common / system / application
父 POM统一版本管理
多环境application-{dev,test,prod}.yml
MyBatis Plus雪花 ID + 逻辑删除 + not_null 更新
Swagger开发期开启,生产期关闭
本地依赖Docker Compose 起 MySQL/Redis

动手练习 ​

  1. 建工程:用 IDEA 创建一个 taskflow-parent 三模块工程,能 mvn clean install 通过
  2. 跑起来:写一个 /api/test/hello 接口,本地启动访问返回 200
  3. 多环境:写 dev 和 prod 两份配置,切换 profile 验证端口、数据库连接都跟着变

下一章:第 6 章:用户模块 →

本站基于 VitePress 构建 · 由 StackHub 团队维护