4. 项目初始化与工程结构:用Spring Cloud Alibaba搭建父工程
好,咱们正式开始动手了。
这一章,我带你从零搭建一个微服务项目的骨架。说白了,就是先把地基打好。你想想看,如果地基歪了,后面盖多少层楼都悬。我在好几个项目里都见过那种「先写业务代码,再回头补工程结构」的团队,结果就是依赖冲突、模块耦合、构建失败……嗯,那滋味可不好受。
4.1 为什么选择Spring Cloud Alibaba?
先聊两句选型的事。
Spring Cloud Alibaba 这套技术栈,我个人习惯用它来搭建微服务。原因很简单:
- 组件成熟:Nacos、Sentinel、Seata 这些组件,已经在阿里内部经过大规模验证
- 中文文档友好:遇到问题,社区里基本能找到答案
- 与Spring Cloud生态兼容:你之前学的Feign、Gateway、Ribbon,都能无缝集成
当然,你也可以用Spring Cloud Netflix那套。但我建议,如果是新项目,直接上Alibaba版本。为什么?因为Netflix很多组件已经进入维护模式了,说白了就是「能用,但不再更新新功能」。
4.2 父工程搭建:Maven多模块的基石
父工程,就是所有子模块的「总管家」。它不写业务代码,只做三件事:
- 统一管理依赖版本
- 定义插件配置
- 声明子模块列表
先创建一个空的Maven项目,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>
<groupId>com.oa</groupId>
<artifactId>oa-microservice</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>OA System Microservice</name>
<!-- 子模块声明 -->
<modules>
<module>oa-common</module>
<module>oa-gateway</module>
<module>oa-auth</module>
<module>oa-business</module>
</modules>
<!-- 统一版本管理 -->
<properties>
<java.version>1.8</java.version>
<spring.boot.version>2.3.12.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.7.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
4.3 子模块创建:四个核心模块
父工程搭好了,接下来创建四个子模块。每个模块都有自己的职责,咱们一个一个说。
4.3.1 oa-common:公共模块
这个模块放什么?所有模块都会用到的东西:
- 统一返回结果类(
Result、PageResult) - 异常定义(
BusinessException、AuthException) - 工具类(
StringUtils、DateUtils) - 常量定义
它的 pom.xml 很简单,几乎不需要额外依赖:
<parent>
<groupId>com.oa</groupId>
<artifactId>oa-microservice</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>oa-common</artifactId>
<packaging>jar</packaging>
4.3.2 oa-gateway:网关模块
网关是系统的「大门」。所有请求先进来,由它做路由、鉴权、限流。我习惯用 Spring Cloud Gateway,性能比 Zuul 好不少。
关键依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
4.3.3 oa-auth:认证授权模块
这个模块负责用户登录、Token 颁发、权限校验。我一般用 Spring Security + OAuth2 来做。注意,这里只做认证,不做业务。
关键依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.oa</groupId>
<artifactId>oa-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
4.3.4 oa-business:业务模块
这是最「胖」的模块。OA 系统的所有业务逻辑——审批流、考勤、公告、会议——都放在这里。当然,如果业务再大一些,我会把它拆成多个子模块(比如 oa-business-approval、oa-business-attendance)。但初期,一个模块就够了。
关键依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.oa</groupId>
<artifactId>oa-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
4.4 工程目录结构一览
搭建完成后,你的项目结构应该是这样的:
oa-microservice/
├── pom.xml # 父工程
├── oa-common/
│ ├── pom.xml
│ └── src/main/java/com/oa/common/
│ ├── result/
│ │ ├── Result.java
│ │ └── PageResult.java
│ ├── exception/
│ │ ├── BusinessException.java
│ │ └── AuthException.java
│ └── util/
│ └── StringUtils.java
├── oa-gateway/
│ ├── pom.xml
│ └── src/main/java/com/oa/gateway/
│ ├── OaGatewayApplication.java
│ └── config/
│ └── RouteConfig.java
├── oa-auth/
│ ├── pom.xml
│ └── src/main/java/com/oa/auth/
│ ├── OaAuthApplication.java
│ ├── config/
│ │ └── SecurityConfig.java
│ └── controller/
│ └── AuthController.java
└── oa-business/
├── pom.xml
└── src/main/java/com/oa/business/
├── OaBusinessApplication.java
├── controller/
├── service/
└── mapper/
Application.java 启动类,一定要放在对应模块的根包下。比如 oa-gateway 的启动类在 com.oa.gateway,而不是 com.oa。否则 Spring Boot 扫描不到组件,启动就报错。我刚开始踩过这个坑,排查了半小时才发现是包路径写错了。
4.5 避坑指南:Maven多模块常见问题
搭建过程中,有几个地方容易出问题。我直接列出来,你对照着检查:
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 子模块找不到父工程 | 子模块 pom.xml 中 parent 配置错误 |
检查 relativePath 是否指向父工程 pom.xml |
| 依赖版本冲突 | 子模块直接引用了未在父工程管理的版本 | 所有依赖版本统一在父工程 dependencyManagement 中声明 |
| 模块间引用失败 | 子模块 A 引用子模块 B,但 B 未先安装到本地仓库 | 先 mvn install 父工程,再构建子模块 |
| 启动类扫描不到其他模块的Bean | 包路径不一致,或者没有添加 @ComponentScan |
确保启动类在根包下,或者显式指定扫描路径 |
pom.xml 后,先执行 mvn clean compile 看看有没有报错。别等到写了几百行代码才发现依赖有问题,那时候改起来就痛苦了。
4.6 本章小结
嗯,这一章的内容就这些。我们做了三件事:
- 搭建了 Maven 父工程,统一管理依赖版本
- 创建了四个子模块:common、gateway、auth、business
- 配置了模块间的依赖关系
下一章,我会带你配置 Nacos 注册中心,让这些模块真正「活」起来。到时候,你就能看到服务之间互相调用了——那才是微服务真正开始的地方。
对了,如果你在搭建过程中遇到任何问题,别硬扛。翻翻官方文档,或者直接来问我。我曾经为了一个依赖冲突折腾到凌晨两点,后来发现只是版本号写错了……这种经历,一次就够了。