Skip to content

模块依赖与循环依赖约束

Forge 对模块间的依赖关系有严格约束,违反约束会导致编译失败或运行时异常。

依赖方向

forge-framework(框架层)
├── forge-dependencies(BOM)
├── forge-starter-parent(技术启动器)
│   └── forge-starter-*(各 Starter)
└── forge-plugin-parent(业务插件)
    └── forge-plugin-*(各 Plugin)

forge-business(业务模块)

forge-admin-server(主应用)

依赖规则

规则说明
Starter → Starter允许(如 cache 依赖 core)
Plugin → Starter允许
Plugin → Plugin禁止互相注入
业务模块 → Starter允许
业务模块 → Plugin允许
Starter → Plugin禁止反向依赖
Starter → 业务模块禁止反向依赖

禁止互相注入

Plugin 之间的 Service 禁止互相注入,这是 Forge 的核心约束之一。

原因

  • 避免 Service 层循环依赖导致 Spring 启动失败
  • 保持 Plugin 的可插拔性(Plugin A 不应因为 Plugin B 不存在而无法启动)
  • 确保职责清晰,跨 Plugin 逻辑上提到 Controller 层

错误示例

java
// ❌ 禁止:Plugin A 的 Service 注入 Plugin B 的 Service
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private CustomerService customerService; // 来自 Plugin B

    public void createOrder(Order order) {
        customerService.updateCustomer(order.getCustomerId());
    }
}

正确做法

java
// ✓ 正确:在 Controller 层协调多个 Service
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;   // Plugin A

    @Autowired
    private CustomerService customerService;  // Plugin B

    @PostMapping("/order")
    public RespInfo<Void> createOrder(@RequestBody Order order) {
        orderService.createOrder(order);
        customerService.updateCustomer(order.getCustomerId());
        return RespInfo.success();
    }
}

事件驱动解耦

当 Plugin 之间需要协作但又不能直接注入时,使用事件机制:

java
// Plugin A 发送事件
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void createOrder(Order order) {
        save(order);
        eventPublisher.publishEvent(new OrderCreatedEvent(order));
    }
}

// Plugin B 监听事件
@Component
public class OrderEventListener {

    @EventListener
    public void onOrderCreated(OrderCreatedEvent event) {
        // 处理订单创建后的逻辑
    }
}

检查循环依赖

编译时检查

Maven 模块依赖关系在编译时检查。如果出现循环依赖,mvn clean install 会报错:

text
[ERROR] The projects in the reactor contain a cyclic reference

运行时检查

Spring 启动时如果检测到 Bean 循环依赖,会抛出 BeanCurrentlyInCreationException

排查方法

  1. 查看完整的异常堆栈
  2. 找到循环链路中的两个 Bean
  3. 将互相注入改为事件驱动或提取到上层

依赖管理 BOM

forge-dependencies 模块统一管理所有依赖版本:

xml
<!-- 在子模块中只需要引入依赖,不需要指定版本 -->
<dependency>
    <groupId>com.mdframe.forge</groupId>
    <artifactId>forge-starter-core</artifactId>
    <!-- 版本由 BOM 统一管理 -->
</dependency>

禁止在子模块中单独指定依赖版本,必须由 BOM 统一管理。

下一步

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架