第 5 章:搭建脚手架
学习目标
- 从零创建 Spring Boot 多模块 Maven 项目
- 配置 application.yml 多环境
- 启动后端并访问 Swagger UI
一、创建多模块项目
用 IDEA 创建一个空的 Maven 父工程,然后手动添加子模块。
步骤:
File → New → Project → Maven不勾 archetype- 命名:
taskflow-parent,GroupIdcom.taskflow - 删除自动生成的
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: bridgebash
docker compose up -d九、本章小结
| 要点 | 关键 |
|---|---|
| 多模块 | parent / common / system / application |
| 父 POM | 统一版本管理 |
| 多环境 | application-{dev,test,prod}.yml |
| MyBatis Plus | 雪花 ID + 逻辑删除 + not_null 更新 |
| Swagger | 开发期开启,生产期关闭 |
| 本地依赖 | Docker Compose 起 MySQL/Redis |
动手练习
- 建工程:用 IDEA 创建一个 taskflow-parent 三模块工程,能
mvn clean install通过 - 跑起来:写一个
/api/test/hello接口,本地启动访问返回 200 - 多环境:写
dev和prod两份配置,切换 profile 验证端口、数据库连接都跟着变
下一章:第 6 章:用户模块 →