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很多组件已经进入维护模式了,说白了就是「能用,但不再更新新功能」。

💡 我的经验:2019年我接手过一个OA系统改造项目,当时用的还是Eureka + Zuul。后来迁移到Nacos + Gateway,整个过程花了整整两周。如果一开始就用Alibaba,能省下不少时间。

4.2 父工程搭建:Maven多模块的基石

父工程,就是所有子模块的「总管家」。它不写业务代码,只做三件事:

  1. 统一管理依赖版本
  2. 定义插件配置
  3. 声明子模块列表

先创建一个空的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>
⚠️ 注意版本兼容性:Spring Boot 2.3.x 对应 Spring Cloud Hoxton.SR12,对应 Alibaba 2.2.x。我曾经见过有人把 Spring Boot 2.4 和 Alibaba 2.2 混用,结果 Nacos 死活连不上。版本号一定要对照官方文档来配。

4.3 子模块创建:四个核心模块

父工程搭好了,接下来创建四个子模块。每个模块都有自己的职责,咱们一个一个说。

4.3.1 oa-common:公共模块

这个模块放什么?所有模块都会用到的东西:

  • 统一返回结果类(ResultPageResult
  • 异常定义(BusinessExceptionAuthException
  • 工具类(StringUtilsDateUtils
  • 常量定义

它的 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-approvaloa-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.xmlparent 配置错误 检查 relativePath 是否指向父工程 pom.xml
依赖版本冲突 子模块直接引用了未在父工程管理的版本 所有依赖版本统一在父工程 dependencyManagement 中声明
模块间引用失败 子模块 A 引用子模块 B,但 B 未先安装到本地仓库 mvn install 父工程,再构建子模块
启动类扫描不到其他模块的Bean 包路径不一致,或者没有添加 @ComponentScan 确保启动类在根包下,或者显式指定扫描路径
🔧 我的小技巧:每次修改 pom.xml 后,先执行 mvn clean compile 看看有没有报错。别等到写了几百行代码才发现依赖有问题,那时候改起来就痛苦了。

4.6 本章小结

嗯,这一章的内容就这些。我们做了三件事:

  • 搭建了 Maven 父工程,统一管理依赖版本
  • 创建了四个子模块:common、gateway、auth、business
  • 配置了模块间的依赖关系

下一章,我会带你配置 Nacos 注册中心,让这些模块真正「活」起来。到时候,你就能看到服务之间互相调用了——那才是微服务真正开始的地方。

对了,如果你在搭建过程中遇到任何问题,别硬扛。翻翻官方文档,或者直接来问我。我曾经为了一个依赖冲突折腾到凌晨两点,后来发现只是版本号写错了……这种经历,一次就够了。