SpringBoot多模块项目解耦策略研究https://www.cnblogs.com/zwj/p/18703793/ai-java-20250208
您可以先阅读上面这篇AI生成的文章,下面是我在工作中的一些实践
已知
1 存在 模块TMS、ERP
2 ERP中引入了TMS的Maven依赖(也就是说 ERP 依赖 TMS)
3 要在TMS里面编写代码,但是涉及到了ERP的业务
解决方案:
TMS模块
- TmsController
- TmsService
TmsService里面存在多个方法,但是没有满足业务需求的,于是在TmsService里面写了一个方法AAA
但是AAA只返回null
接着,在ERP里面创建一个EepExtendsTmsService,继承 TmsService,同时添加注解@Primary
然后重写 AAA方法
@Primary 是 Spring 框架中的一个注解,用于在存在多个相同类型的 Bean 时,指定优先使用的 Bean。
这个时候,ERP的业务就还在ERP模块里面
而TMS模块,也能通过调用TMS模块的AAA方法,来满足需求
这个方案也就是最终提交的的版本
在这个方案之前,我是使用接口的方式实现的,如下:
1 在TMS创建Interface接口文件
2 在ERP里面实现这个接口文件
下面是AI回答:
在多模块项目中,如果 ERP 模块导入了 TMS 模块的 Maven 依赖,并且需要实现业务逻辑分散到各自模块中(ERP 模块负责数据表操作,TMS 模块提供通用业务逻辑框架),可以使用以下表格形式呈现解决方案的对比:
解决方案对比
特性/方案 | 接口 | 抽象类 | 继承 | 组合(依赖注入) |
---|---|---|---|---|
耦合度 | 低 | 中 | 高 | 低 |
是否支持多实现 | 支持 | 不支持 | 不支持 | 支持 |
是否能包含字段 | 不可以直接包含字段 | 可以 | 可以 | 通过依赖注入的对象访问 |
是否能包含方法实现 | Java 8+ 可以包含默认方法 | 可以 | 可以 | 通过依赖注入的对象调用 |
适用场景 | 定义行为规范,完全解耦 | 提供部分实现,减少重复代码 | 层次化设计,共享核心逻辑 | 灵活扩展,推荐的最佳实践 |
父模块提供默认实现 | 需要额外工具(如默认方法) | 可以 | 可以 | 通过依赖注入的对象实现 |
子模块扩展性 | 高 | 中 | 中 | 高 |
维护成本 | 较低 | 中 | 较高 | 较低 |
具体建议
1. 使用组合(依赖注入)
- 原因 :
- ERP 模块导入了 TMS 模块的依赖,说明 TMS 模块提供了某些通用功能或服务。
- 如果 ERP 模块需要操作自己的数据表,可以通过依赖注入的方式将 ERP 的数据操作类传递给 TMS 模块。
- 实现方式 :
- TMS 模块定义一个接口或抽象类,表示数据操作的行为。
- ERP 模块实现该接口或抽象类,并完成具体的数据表操作。
- TMS 模块通过依赖注入的方式获取 ERP 的实现类,并调用其方法。
java
// TMS 模块:定义接口
public interface DataOperationService {
void processData(String data);
}
// ERP 模块:实现接口
@Service
public class ErpDataOperationService implements DataOperationService {
@Override
public void processData(String data) {
// 具体的数据表操作逻辑
System.out.println("ERP 数据处理: " + data);
}
}
// TMS 模块:通过依赖注入使用 ERP 的实现
@Service
public class TmsBusinessService {
private final DataOperationService dataOperationService;
public TmsBusinessService(DataOperationService dataOperationService) {
this.dataOperationService = dataOperationService;
}
public void executeBusinessLogic(String data) {
// 调用 ERP 的数据操作逻辑
dataOperationService.processData(data);
}
}
2. 使用抽象类
- 原因 :
- 如果 TMS 模块需要提供一些默认实现(例如通用业务逻辑),而 ERP 模块只需要扩展特定的数据操作逻辑,可以使用抽象类。
- 实现方式 :
- TMS 模块定义抽象类,并提供通用逻辑。
- ERP 模块继承该抽象类,并实现具体的数据操作方法。
java
// TMS 模块:定义抽象类
public abstract class AbstractBusinessService {
protected void commonLogic() {
System.out.println("执行通用逻辑...");
}
public abstract void processData(String data);
public void execute(String data) {
commonLogic();
processData(data);
}
}
// ERP 模块:继承抽象类
@Service
public class ErpBusinessService extends AbstractBusinessService {
@Override
public void processData(String data) {
// 具体的数据表操作逻辑
System.out.println("ERP 数据处理: " + data);
}
}
3. 使用接口
- 原因 :
- 如果 TMS 模块只需要定义行为规范,而不关心具体实现,可以使用接口。
- 实现方式 :
- TMS 模块定义接口。
- ERP 模块实现接口,并完成具体的数据操作逻辑。
- TMS 模块通过接口调用 ERP 的实现。
java
// TMS 模块:定义接口
public interface BusinessService {
void execute(String data);
}
// ERP 模块:实现接口
@Service
public class ErpBusinessServiceImpl implements BusinessService {
@Override
public void execute(String data) {
// 具体的数据表操作逻辑
System.out.println("ERP 业务逻辑执行: " + data);
}
}
总结
- 推荐方案 :组合(依赖注入)。
- 理由:灵活性高,模块间耦合度低,易于扩展和维护。
- 备选方案 :抽象类。
- 理由:适用于需要提供部分默认实现的场景。
- 不推荐方案 :直接继承。
- 理由:耦合度高,不利于模块独立性和扩展性。