后端架构笔记之Maven多模块与微服务

上一篇:后端笔记之Maven配置以及解决Maven中央仓库没有的依赖

上一篇里提到依赖时,子模块会继承父项目的驱动依赖,因为项目是多模块结构,该篇区分Maven多模块与微服务 。

Maven 多模块 = 代码层面拆分;微服务 = 运行时独立部署拆分。

现在项目只是代码仓库内分层,所有模块最终打包后依然跑在同一个进程、同一个服务实例里,这叫模块化单体项目,不是微服务。

一、结构

1、Maven 多模块

bash 复制代码
parent(父工程,统一管理版本)
├─ module-api    接口、DTO实体类
├─ module-service 业务逻辑
├─ module-mapper 数据库操作
└─ module-web    启动类、Controller

本质特点:

  1. 只是代码组织方式:把代码分成不同子模块,方便包管理、依赖隔离;
  2. 最终打成一个 Jar;
  3. 只有一个 main 启动类,启动之后所有模块代码运行在同一个 JVM 进程;
  4. 模块之间调用:本地 Java 方法直接调用,不存在网络请求、远程调用。

调用方式:A模块直接new对象 / Spring注入调用B模块方法,进程内调用,没有 HTTP/RPC。

bash 复制代码
类比:一栋大房子,只是室内用墙隔成客厅、卧室、厨房,房子仍然是一栋建筑,进出同一个大门。

2、微服务

微服务每一个业务模块独立工程、独立仓库(或独立子项目)、独立启动类、独立打包、独立进程、独立端口。

bash 复制代码
订单服务(独立jar,8081端口,单独启动)
用户服务(独立jar,8082端口,单独启动)
库存服务(独立jar,8083端口,单独启动)
  • 服务和服务之间:跨进程网络调用(OpenFeign/Dubbo RPC)
  • 一个服务崩溃,理论上不直接拖垮其他服务
  • 可以单独部署、单独扩容
bash 复制代码
类比:直接拆成好几栋独立小屋,每栋房子单独大门,屋子之间交流需要打电话(网络请求)。

3、两者关键对比表

4、 误区

误区:代码分成多个 maven 子模块 = 微服务

真相:代码分层 ≠ 服务拆分

新手项目:

用 maven 多模块分出 user、order 模块,就自称微服务。

但是:所有模块打包进同一个 jar,一起启动,模块之间直接本地调用。

这只是工程代码模块化,架构依旧是单体架构。

5、例子

场景:电商下单

① Maven 多模块单体(你的项目)

web 模块收到请求 → 本地调用 order 模块方法 → 本地调用 stock 模块扣库存

全程:进程内方法调用,没有网络。

② 微服务架构

网关接收请求 → 调用【订单服务 (8081)】 → 订单服务通过 HTTP/RPC 远程请求【库存服务 (8082)】

两次不同进程之间网络通信。

6、延伸:「多模块单体」改成真正微服务

把 order、user 等子模块,抽离成独立 SpringBoot 项目,各自拥有启动类;

模块间本地方法调用,改成远程调用(Dubbo / OpenFeign);

引入注册中心 Nacos、网关、服务治理组件;

每个服务独立打包、独立部署。

7、总结

Maven 多模块只是源代码层面的逻辑分层,用来规范代码结构、统一依赖管理;所有子模块最终合并运行在同一个进程,不存在跨服务网络调用。

微服务是部署运行层面的物理拆分,业务单元独立进程、独立部署,依靠网络完成互相通信。

二者维度完全不同,不能混为一谈。

二、差异

代码层面(pom.xml + 工程结构 + 打包运行逻辑)三处决定性差异

① 普通 Maven 多模块(单体架构常用)

场景:项目拆多个模块,最终只会打出 1 个可执行 Jar

例如:父 pom → core、dao、web;只有 web 模块带启动类,其他都是 jar 依赖。

运行:一个进程。

② SpringCloud Maven 多模块(微服务聚合工程)

场景:父 pom 聚合,每一个 service 子模块都是独立 SpringBoot 应用,各自打包独立 Jar、独立进程、独立部署。

运行:N 个进程。

1、pom.xml 代码上直观区别

区别 1:modules 内子模块定位不同
(1)【普通多模块(单体)】结构
bash 复制代码
parent(pom)
├─ module-core        jar包,工具/实体
├─ module-dao         jar包,持久层
└─ module-web         唯一带启动类、唯一可执行模块

父 pom modules 列表:

xml 复制代码
<modules>
    <module>module-core</module>
    <module>module-dao</module>
    <module>module-web</module>
</modules>
bash 复制代码
只有 module-web 能运行;core/dao 仅仅是依赖库,不能单独启动。
(2)【SpringCloud 微服务多模块】结构
bash 复制代码
parent(pom)
├─ spring-cloud-common      公共jar库(无启动类)
├─ spring-cloud-gateway     独立应用,可启动
├─ spring-cloud-service-user 独立应用,可启动
└─ spring-cloud-service-order 独立应用,可启动

父 pom modules 列表:

xml 复制代码
<modules>
    <module>spring-cloud-common</module>
    <module>spring-cloud-gateway</module>
    <module>spring-cloud-service-user</module>
    <module>spring-cloud-service-order</module>
</modules>
bash 复制代码
gateway / user / order 全部拥有独立启动类,均可单独打包、单独启动
区别 2:子模块 pom 打包插件配置差异

普通单体多模块

  • core、dao:没有 spring-boot-maven-plugin
  • 仅 web 模块存在打包插件,最终构建出唯一可执行 jar
xml 复制代码
<!-- 仅web模块才有 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

SpringCloud 微服务多模块

  • 所有业务服务模块(gateway、user、order)各自都配置 spring-boot-maven-plugin
  • 每个模块都能独立打成可执行 jar:
xml 复制代码
<!-- service-user pom -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.demo.cloud.user.UserApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>
bash 复制代码
common 模块依然不加此插件,只是基础依赖包。
区别 3:依赖清单代码差异

普通单体多模块 web 模块依赖

只有基础 web、mybatis,没有微服务组件

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.xxx</groupId>
        <artifactId>module-core</artifactId>
    </dependency>
</dependencies>

SpringCloud 微服务模块依赖

多出Spring Cloud 微服务生态依赖(代码层面最明显标识)

xml 复制代码
<!-- 注册中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 远程调用 OpenFeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
区别 4:启动类注解代码区别

普通单体项目启动类

java 复制代码
@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

SpringCloud 微服务启动类

增加微服务相关注解(代码特征)

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient // 服务注册到注册中心
@EnableFeignClients    // 开启远程调用
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}
区别 5:配置文件差异

普通单体:application.yml

微服务:通常配套 bootstrap.yml(用于 Nacos 配置中心加载),配置内包含服务名、nacos 地址

yaml 复制代码
spring:
  application:
    name: service-user # 服务唯一名称,注册中心识别
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848

2、Maven 命令构建行为差异

普通单体多模块

执行 mvn clean package

  1. 先编译 core → dao
  2. 最后打包 web

产物只有一个可执行 jar:module-web.jar

启动:java -jar module-web.jar 只启动一个进程

SpringCloud 微服务聚合多模块

执行 mvn clean package

产物:

  • spring-cloud-common.jar(普通依赖包)
  • spring-cloud-gateway.jar(可执行)
  • spring-cloud-service-user.jar(可执行)
  • spring-cloud-service-order.jar(可执行)

你可以选择性启动任意服务:

bash 复制代码
java -jar spring-cloud-gateway.jar
java -jar spring-cloud-service-user.jar
java -jar spring-cloud-service-order.jar

3、汇总

4、误区

代码形式都是 Maven 聚合父工程,语法没有任何特殊新标签!

不存在 Maven 有两套语法;区别不在 Maven 语法,在于模块职责划分、依赖引入、运行设计。

也就是说:

把一个普通多模块项目,新增多个带启动类的子模块、引入 Nacos、加上服务注解,它就变成微服务聚合工程。

相关推荐
特立独行的猫a9 小时前
一切皆插件:DeepSeek Harness 的架构哲学,以及与主流 Agent 的对比
人工智能·架构·agent·deepseek·harness
雨白10 小时前
我的 UML 学习笔记:结合 Android 实例看懂 4 种常用图表
android·架构
heimeiyingwang10 小时前
【架构实战】OpenTelemetry链路追踪实战:从零到生产的完整指南
架构
mldong10 小时前
用 DDD 设计工作流引擎:聚合根与充血模型
java·架构
candyTong11 小时前
Claude Code 如何恢复一段会话
后端·架构·ai编程
PC2005-cloud13 小时前
DeepSeek Harness 创建 skill 指南:结构、安装、使用
笔记·学习
段一凡-华北理工大学14 小时前
AI推动工业智能化转型~系列文章20:工业 AI 平台架构:云-边-端协同的技术体系
人工智能·python·架构·工业平台·云-边协同
CodeBlog-star14 小时前
Harness Engineering:Pi Agent 架构深度解析
人工智能·python·架构·harness工程
IT大白鼠14 小时前
OpenBao开源密钥管理系统:技术架构、核心功能与行业应用研究
架构·开源·aiops·openbao