为什么很多人(包括你)会觉得 Java 的模块化(JPMS,Java Platform Module System)很鸡肋?
其实这个感觉非常普遍,尤其是在 2017–2025 年这段时间内,几乎是 Java 社区最两极分化的特性之一。下面我试着把最常见的“鸡肋感”来源,以及它真正有价值的地方都摊开来说清楚。
大多数人觉得鸡肋的真实原因(前 8 大痛点)
- 启动时多了一堆 –add-opens / –add-exports 参数
这是目前最让人崩溃的地方。
很多第三方库(尤其是反射重的框架:Spring、Hibernate、Jackson、MyBatis、Lombok、Mockito、ByteBuddy ……)在 Java 9+ 都开始报错,必须手动加一堆--add-opens参数才能跑起来。 - 迁移成本极高,收益却看不见
把一个普通 Maven/Gradle 项目改成模块化项目,通常需要:
- 给每个 jar 都加 module-info.java
- 处理大量 split package 冲突
- 修改构建脚本
- 修一堆反射、代理、动态类加载的问题
改完之后……用户几乎感觉不到任何变化,性能也没明显提升 → 性价比极低。
- 模块路径 vs 类路径的割裂感很强
一旦用了模块化,就必须区分 classpath 和 module-path,
很多依赖同时存在两种模式,构建工具支持得并不完美(尤其是早期 Maven/Gradle 插件)。 - 模块化对库作者友好,对应用开发者不友好
模块化真正解决的是库开发者的封装和版本兼容问题(强封装、可靠配置),
但对最终应用开发者来说,99% 的场景下只是增加了配置负担。 - 强封装反而把反射玩坏了
以前随便反射访问内部字段/方法都行,现在必须被模块明确开放(opens / exports),
导致大量老代码、老框架直接挂掉,而新框架又不愿意为了模块化牺牲灵活性。 - 实际项目中用到的模块化功能非常少
大部分团队真正用到的只有:
- requires java.base(默认就有)
- requires java.sql / java.xml 之类
其他高级功能(provides、uses、open、exports ……)几乎没人用。
- 启动性能反而变差的案例不少
模块扫描、模块解析、强封装检查这些额外工作,在中小项目上反而让冷启动变慢了。 - 社区接受度低 → 生态跟不上
很多热门库到 2025 年底仍然没有提供完整的 module-info.java,
或者提供了但不完整,导致“要么不用模块化,要么自己修”。
那它到底有没有价值?什么时候不鸡肋?
模块化真正有价值的地方,主要集中在以下几种场景:
| 场景 | 模块化带来的真实收益 | 典型代表项目 / 公司 |
|---|---|---|
| 大型单体 → 模块拆分 | 强制依赖清晰、防止非法访问内部 API | JDK 自身、IntelliJ IDEA、Eclipse |
| 需要极致强封装的库 | 隐藏实现细节、防止用户直接依赖内部类 | java.base、java.desktop 等 JDK 模块 |
| 安全敏感系统(金融、军工) | 限制反射、限制非法访问,降低攻击面 | 部分银行、航空航天系统 |
| 自定义运行时(jlink / jpackage) | 显著减小镜像体积(从 200MB → 50MB 很常见) | GraalVM Native Image、jlink 镜像 |
| 长期维护的大型企业内部框架 | 强制模块边界,防止下游随意依赖内部实现 | 一些超大型央企/银行自研框架 |
一句话总结:
对 95% 的普通 Web 后端、Spring Boot 项目来说,模块化目前确实“鸡肋”甚至是“负收益”。
但对 JDK 自身、超大型框架、需要极致裁剪的云原生镜像、强安全需求的系统来说,它的价值是实打实的。
2025–2026 年的现实建议
| 项目规模 / 类型 | 推荐做法 | 理由简述 |
|---|---|---|
| 普通 Spring Boot / 中小型项目 | 完全不使用模块化(module-info.java 不要加) | 收益几乎为 0,成本却很高 |
| 中大型单体项目 | 可以考虑在内部模块之间使用,但不要强推到第三方依赖 | 折中方案,控制成本 |
| 需要打 jlink / GraalVM 原生镜像 | 强烈建议使用模块化 | 体积和启动速度收益明显 |
| 自己开发长期维护的框架/组件 | 尽量做模块化 + 提供完整的 module-info | 对下游用户更友好 |
总结一句话回答你的疑问:
你感觉鸡肋是非常正常的,因为对当下绝大多数 Java 业务开发者来说,JPMS 的成本 >> 收益。
它更像是给 JDK 和超大型框架准备的“未来基础设施”,而不是给普通 CRUD 业务准备的日常工具。
如果你现在在纠结要不要给自己的项目加 module-info.java,欢迎把项目规模、打包方式(fatjar / jlink / native)、团队情况说一下,我可以给你更具体的建议。