如何解决 Maven 中的循环依赖?

Posted

技术标签:

【中文标题】如何解决 Maven 中的循环依赖?【英文标题】:How to resolve cyclic dependency in Maven? 【发布时间】:2013-05-04 07:51:25 【问题描述】:

我们如何解决 Maven 循环依赖?

假设 A 是父项目,B 和 C 是子项目。如果 B 依赖于 C 并且 C 依赖于 B,除了拥有不同的项目之外,还有什么方法可以解决循环依赖关系。

【问题讨论】:

你已经排除了创建一个新项目的可能性,这就是我会做的......你有什么理由不想这样做?这将是最好的解决方案。 如果不能新建项目,能不能把所有依赖的功能只移到B或者C? maven 所做的是将“周期性依赖不良”提升到项目级别,这是非常有限的。如果您在 java 中的代码(类)级别具有真正的循环依赖,那肯定是不好的......或者只是愚蠢。但在项目层面???快点。那只是限制自己。模块之间的交叉依赖并不“完美”,但它有一个用例。只要它不会转化为任何不良的运行时案例。某些类可能出于遗留原因等原因需要代码。这是一个愚蠢的 Maven 约定,构成了容易上当、懒惰的程序员的思想。 【参考方案1】:

Maven 不允许项目之间的循环依赖,否则将不清楚首先构建哪个项目。所以你需要摆脱这个循环。一种解决方案是您已经提到的用于创建另一个项目的解决方案。另一种方法是将一些类从 B 移动到 C,反之亦然。或者有时如果不需要两个项目,将项目 B 和 C 合并为一个项目是正确的。

但如果不了解和分析您的项目为何相互依赖,就很难提出最佳解决方案。

所以我建议您可以使用JDepend 或InteliJ 分析工具等工具来查找有问题的类,并根据它们为您的软件找到更好的设计。

大多数时候,我会创建一个接口模块和实现模块之类的东西,这样可以摆脱大多数循环。 在这个线程中查看 Dormouse 的答案并搜索 Dependency Inversion Principle 以获取有关此主题的更多资源。

【讨论】:

查找依赖项的一个廉价技巧是删除您遇到问题的那个,然后查看编译器抱怨的地方。 嗨@mszallbach,你能解释一下你如何使用接口模块和实现模块来摆脱循环吗? @Nathalie 检查来自 Dormouse 的答案以及相应的 Wiki 链接到 Dependency Inversion Principle。当你搜索依赖倒置原则时,应该有很多来源。【参考方案2】:

创建一个新项目确实是一种解决方案。

依赖倒置是第二种可能的解决方案。

非循环依赖原理参考here。

还有here 依赖倒置原则。

【讨论】:

【参考方案3】:

我将介绍我如何解决这些循环依赖问题。

我有两个相互包含的模块。我删除了每一方的依赖关系并设置了 RabbitMQ 消息系统并创建了直接交换。所以当我需要来自 module1 的东西时,我会向 RabbitMQ 发送消息并从 module2 获取响应和处理数据。我认为这是集成组件的更好方式,而且是松散集成。

【讨论】:

【参考方案4】:

假设 A 项目依赖于 B,B 依赖于 A。

    创建新项目并移动所有常用类。这是第一个首选选项。如果不选择选项 2。 尝试将一个依赖项作为运行时依赖项(例如,A 是编译时依赖于 B,B 是运行时依赖于 A)。这将有助于解决首先构建哪个 jar。在这种情况下,应该先构建 B jar,然后再构建 A。这里,运行时意味着可以通过反射调用 API。

【讨论】:

以上是关于如何解决 Maven 中的循环依赖?的主要内容,如果未能解决你的问题,请参考以下文章

maven包循环依赖。导致溢出定位加解决

面试题:如何解决Spring 的循环依赖问题

如何解决xcode中的循环依赖错误

Spring到底是如何解决循环依赖的?

0源码基础学习Spring源码系列——Spring如何解决循环依赖

Spring — 循环依赖