若依框架做大了怎么办?多模块 Maven 拆分的完整指南

若依项目做到第三个月,admin 模块越来越臃肿------启动 40 秒、改一行代码全量编译、两个人改同一个文件天天冲突。这篇文章复盘我是怎么把若依从单模块拆成多模块的:哪个先拆、边界怎么画、依赖怎么管、趟过的坑一个不落。


一、单体项目的"三个月魔咒"

最开始搭若依的时候,目录干净得让人舒服。前两周没毛病,改什么都快。

问题从第一个月开始冒头:

症状 具体表现 谁难受
启动变慢 从 8 秒涨到 40 秒 每次调试都等得心烦
编译范围大 改一行 Service,全量 300+ 类重新编译 浪费时间
合并冲突 两个人都在 admin 里加东西,每天 merge 都有冲突 协作成本飙升
边界模糊 CRM 的 Service 和 MES 的 Service 混在一起,越写越不敢删 谁敢重构谁死

到第二个月底,ruoyi-admin 已经塞了 CRM 模块和 MES 模块的全部代码------Controller 40 多个,Service 30 多个,Mapper 50 多个。

单模块不坏,但当你开始纠结"这个类该放哪个包"的时候,就是该拆的时候了。


二、若依框架的模块化设计全景

先看若依官方给的标准模块结构:

perl 复制代码
ruoyi/
├── ruoyi-common/        # 公共工具类、异常、注解、枚举
├── ruoyi-framework/     # 框架核心配置(安全、数据源、Swagger)
├── ruoyi-system/        # 系统管理业务(用户、角色、菜单、部门)
├── ruoyi-generator/     # 代码生成器
├── ruoyi-quartz/        # 定时任务
└── ruoyi-admin/         # 启动模块 + Controller 汇总

依赖链路:只向下,不向上

perl 复制代码
ruoyi-admin  ──→  ruoyi-system  ──→  ruoyi-framework  ──→  ruoyi-common
   (顶层)          (业务层)          (配置层)            (基础层)

没有任何一个底层模块依赖上层模块。 这是 Maven 多模块拆分的第一铁律。


三、实战第一步:把业务模块从 admin 里拆出来

Step 1:创建新模块

pom.xml<modules> 里加一行:

xml 复制代码
<modules>
    <module>ruoyi-common</module>
    <module>ruoyi-framework</module>
    <!-- ... 其他模块 ... -->
    <module>ruoyi-crm</module>        <!-- 新增 -->
</modules>

新建 ruoyi-crm/pom.xml

xml 复制代码
<parent>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>3.3.0</version>
</parent>

<artifactId>ruoyi-crm</artifactId>

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

⚠️ 关键:ruoyi-crm 不要依赖 ruoyi-admin。admin 是顶层,业务模块不能反向依赖。

Step 2:迁移代码

bash 复制代码
ruoyi-crm/
├── pom.xml
└── src/main/java/com/ruoyi/crm/
    ├── controller/     ← 从 admin 搬过来
    ├── service/
    ├── service/impl/
    ├── mapper/
    └── domain/

包路径变了:com.ruoyi.web.controller.crmcom.ruoyi.crm.controller,IDE 批量替换即可。

Step 3:admin 加上依赖

xml 复制代码
<!-- ruoyi-admin/pom.xml -->
<dependency>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi-crm</artifactId>
</dependency>

第一个坑:Spring Boot 扫描不到 Bean

代码搬过去,启动报 NoSuchBeanDefinitionException

根因@MapperScan 还在 admin 里指向老路径。

解决 :把 @MapperScan 放到各模块自己内部:

less 复制代码
// ruoyi-crm 模块中
@Configuration
@MapperScan("com.ruoyi.crm.mapper")
public class CrmConfig {
}

四、实战第二步:公共代码怎么不重复

拆完 CRM 和 MES 后,两个模块都需要 ExcelUtil

错误的做法:各 copy 一份。正确做法:抽到 ruoyi-common

bash 复制代码
ruoyi-common/src/main/java/com/ruoyi/common/utils/
├── ExcelUtil.java          # CRM 和 MES 都用
├── PageUtils.java           # 通用分页工具
└── DictUtils.java           # 字典工具

什么时候不该放 common?

CRM 和 MES 之间有一个共享 DTO------CrmCustomerBriefDTO。如果放 common,common 会逐步膨胀成大杂烩。

方案 :建一个 ruoyi-shared-dto 模块,只放跨模块共享的数据对象,common 保持干净。

common 的使命是"基础能力",不是"业务共享"。


五、实战第三步:多模块下的配置管理

每个模块不能各配各的。 Spring Boot 启动时只加载一次 application.yml,位置在 admin 的 resources 里。

模块专属配置用 @ConfigurationProperties + 前缀隔离:

less 复制代码
// ruoyi-crm 模块中
@Data
@Component
@ConfigurationProperties(prefix = "crm")
public class CrmConfig {
    private int importMaxRows = 5000;
    private int opportunityExpireDays = 30;
}
arduino 复制代码
# application.yml(只在 admin 中维护)
crm:
  import-max-rows: 5000
  opportunity-expire-days: 30

所有 yml 文件都放 ruoyi-admin/src/main/resources/,业务模块只定义 @ConfigurationProperties 类。


六、Maven 多模块构建与打包

版本号统一

xml 复制代码
<!-- 根 pom.xml -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
            <version>${ruoyi.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块引用不写版本号,由根 pom 统一管控。

第二个大坑:循环依赖

CRM 依赖 MES、MES 又依赖 CRM → Circular dependency

解法:提取接口到 common,依赖接口而非依赖实现:

kotlin 复制代码
// ruoyi-common 中定义接口
public interface CustomerBriefService {
    CustomerBriefDTO getBrief(Long customerId);
}

// ruoyi-crm 中实现接口
@Service
public class CustomerBriefServiceImpl implements CustomerBriefService { ... }

// ruoyi-mes 中依赖接口,不依赖模块本身
@Service
public class QualityCheckService {
    @Autowired
    private CustomerBriefService customerBriefService;  // 注入接口
}

MES 只依赖 common 中的接口,不依赖 CRM 模块------循环依赖解了。


七、拆分后的收益

维度 拆之前 拆之后
启动时间 ~40 秒 ~18 秒
编译时间 改一行全量 300+ 类 只编译当前模块
代码冲突 天天 merge 冲突 基本不冲突
新人上手 要弄懂整个 admin 读懂一个模块就能开工
删除成本 不敢删 Maven 依赖图一眼看穿,敢删

八、总结

三条核心原则回顾:

① 依赖只向下。 底层模块永远不依赖上层。

② 公共代码提 common,业务代码放模块。 common 是基础能力集,不是垃圾桶。

③ 一次只拆一个模块。 拆一个,跑通,再拆下一个。

什么时候该拆?

  • 启动时间超过 30 秒?
  • 两个人以上在同一个模块里写代码?
  • 你开始纠结"这个类到底该放哪个包"?

两个满足了就动手。拆分是为协作和长期维护服务的,不要为了拆而拆。


关于作者

我是一名全栈开发者,目前在深圳创业,专注于印刷包装行业的数字化系统建设。

技术栈:Java / Spring Boot / Vue3 / uni-app / MySQL / Redis

我会持续分享全栈开发实战、若依框架深度教程、MES & CRM 产品设计思路。若依框架实战系列还有:

每周更新,欢迎关注微信公众号「MqCode」,第一时间获取全栈开发实战内容 👇

相关推荐
用户40269244819081 小时前
CRMEB Pro 新增后台接口全链路:路由、权限、验证器、返回格式一次讲清
前端·后端
考虑考虑1 小时前
Java实现hmacsha1加密算法
java·后端·java ee
程序边界2 小时前
lac_agent自愈链路上篇——crontab守护的那些坑与健康检查实战
后端
笨鸟飞不快2 小时前
从 MVC 到 DDD:一次真实的渐进式迁移实录
后端·架构
程序员威哥2 小时前
C#也能玩转YOLO:工业视觉原生推理方案,零Python依赖
后端
kfaino2 小时前
你好,我叫 Prompt——其实,你一直在给 AI 写程序
后端·openai·ai编程
caibixyy3 小时前
springboot+langchain4j实战Day 16 — 混合检索 + Reranker 重排序
后端
Ai拆代码的曹操3 小时前
揭秘"幽灵 CPU":top 抓不到的短命进程,才是真正的 CPU 杀手
后端
IT_陈寒3 小时前
Python里这个赋值坑,连老司机都能翻车
前端·人工智能·后端