Spring Modulith 入门与实战
📅 积木成林,经过一段时间对模块化结构的论证和实践,Spring 社区接续推出了 Spring Modulith 这样一套规范! 📊
Spring Modulith 自身简洁而有效,目标是在 Spring Boot 项目中实现逻辑模块,支持构造清晰的结构依赖,完善实现分层隔离,并提供验证、文档、测试和观测支持。✨
🛠️ 什么是 Spring Modulith? 🏋️
💭 在 Spring Modulith 中,一个 Application Module 是一个逻辑单元,包括:
- 对外 API:提供给其他模块调用的 Bean 或事件;
- 内部组件:不应该被其他模块直接使用;
- 必需接口:依赖于其他模块提供的功能。
🌬️ 模块化的目标是:涉入分层,控制依赖,维持单元自立。
💡 快速分析模块 🔢
🎓 创建模块模型,只需:
var modules = ApplicationModules.of(Application.class);
modules.forEach(System.out::println);
📈 输出的模块信息:
## example.inventory ##
> Base package: example.inventory
> Spring beans: InventoryManagement, SomeInternalComponent
🌐 模块分组根据 package 结构分析,美观而自然。
🔄 模块类型:简单和高级 🌟
- 简单模块:直接子包,全部 public 类为 API,内部通过 package-private 隔离;
- 高级模块:有子包,internal 分组,隔离不应依赖的组件。
🔹 嵌套模块设计 🚷️
🛂 如果一个模块内部需再分层,可将子 package 标注为嵌套模块:
@ApplicationModule
package example.inventory.nested;
🛠️ 嵌套模块可访问父模块,但外部不能访问它。
🛡️ Open 模块:旧项目迁移工具 🛋️
🛆 迁移旧项目时,可把模块标记为 OPEN:
@ApplicationModule(type = Type.OPEN)
package example.inventory;
🔓 允许其他模块访问 internal 类,但应阶次性处理,促进完全隔离。
📢 明确声明模块依赖 🔗
📐 限定依赖模块,通过 allowedDependencies:
@ApplicationModule(allowedDependencies = "order")
package example.inventory;
🌊 只想依赖指定 Named Interface,可使用 "order :: spi"。
🌍 Named Interfaces 与展示接口 🔍
💼 将指定 package 标注为 Named Interface:
@NamedInterface("spi")
package example.order.spi;
📆 让其他模块仅依赖该接口。
📚 简化配置:@Modulithic 🎓
📣 在 Spring Boot 主类上使用:
@Modulithic(systemName = "Inventory Management", sharedModules = {"common"}, additionalPackages = {"com.example.common"})
@SpringBootApplication
class MyApplication {}
🌓 一次性管理模块配置,简洁效率。
👨💼 自定义模块检测策略 🔍
📌 如需自定义 module discovery:
class CustomApplicationModuleDetectionStrategy implements ApplicationModuleDetectionStrategy {
@Override
public Stream<JavaPackage> getModuleBasePackages(JavaPackage basePackage) {
// 根据命名规则选择
}
}
📢 配置:
spring.modulith.detection-strategy=example.CustomApplicationModuleDetectionStrategy
🌟 结论 🌟
📆 Spring Modulith 是一套简洁而有效的模块化工具,适合为 Spring Boot 应用增强结构隔离和可维护性! 💫
🎉 无需大量修改现有代码,同时为将来的分层、分子服务进化打了基础。✨