50

我在 maven 项目方面有几年的经验,即使是多模块项目(这让我讨厌maven 的多模块功能(所以免责声明现在已经完成)),即使我真的很喜欢 maven,但有些东西我无法得到明确回答:

多模块 Maven 项目的典型用例是什么?与简单的依赖关系和父 pom 相比,这种结构的附加值是什么?

我已经看到了很多多模块项目的配置,但是所有这些都可以通过创建一个简单的依赖库结构来明确解决,这些依赖库作为可交付成果过着自己的生活(即使使用父 pom,作为单独的可交付成果:分解依赖和配置) ) 而且我还没有找到任何可以清楚地看到多模块结构的附加值的用例。

我一直发现这种结构会带来过度的复杂性而没有真正的好处:我在哪里遗漏了什么?(说实话,我知道有些人ear可以从这种结构中受益,但除了那个特定的用例之外,还有其他真正的用途和好处吗?)

4

5 回答 5

35

这是一个真实的案例。

我有一个多模块项目(你的咆哮......我没有看到它有任何复杂性。)最终结果是一个 webapp,但我有不同的模块用于 api、impl 和 webapp。

创建项目 12 个月后,我发现我必须使用从 jar 运行的独立进程与 Amazon S3 集成。我添加了一个依赖于 api/impl 的新模块,并为新模块中的集成编写代码。我使用程序集插件(或类似的东西)来创建一个可运行的 jar,现在我有一个可以在 tomcat 中部署的战争和一个可以在另一台服务器上部署的进程。我的 S3 集成过程中没有 Web 类,我的 Web 应用程序中没有 Amazon 依赖项,但我可以共享 api 和 impl 中的所有内容。

3 个月后,我们决定创建一个 REST webapp。我们希望将其作为一个单独的应用程序来完成,而不仅仅是现有 web 应用程序中的新 URL 映射。简单的。又一个模块,另一个 webapp 是 maven 构建的结果,没有特别的修改。业务逻辑在 webapp 和 rest-webapp 之间很容易共享,我可以根据需要部署它们。

于 2013-03-21T22:39:00.083 回答
17

多模块的主要好处是

  • 一个 Maven 命令一次构建所有模块。
  • 最重要的是:maven 会为您处理构建顺序。
  • 配置你的 CI 服务器也很容易:一个 jenkins 的工作来构建所有东西。

我已经在一个包含大约 30 个子模块的项目中工作过。有时,您需要更改模块以外的内容,并且运行一个命令并确保需要编译的所有内容都以正确的顺序编译是必须的。

编辑

为什么要 30 个子模块?

具有大量功能、大量开发人员、基于模块的功能分离的庞大框架。这是一个现实生活中的用例,将代码分离到模块中非常有意义。

于 2013-03-21T22:13:58.717 回答
4

我认为您在大多数使用多模块的项目中是正确的,实际上并不需要它们。

在我工作的地方,我们使用多模块项目(我认为这是有充分理由的)。我们有一些类似于面向服务的架构,所以每个应用程序

  • 客户端模块
  • 接口模块(在客户端和实现之间具有共享对象)
  • 一个实现模块
  • 战争模块

我同意将实现和战争模块放在同一个实际模块中是可以的,但是(可以说)这样做的好处是解决问题的类之间非常明确的划分以及应用程序如何与外部世界通信。

在以前只涉及 Web 应用程序的项目中,我尝试将所有内容放在同一个模块中,因为考虑到我正在使用的模块,它使测试更容易。

于 2013-03-21T22:08:39.140 回答
1

多模块可以帮助您重用代码。这是您在工作中感受到的最大好处之一。

想象一下,如果您有 3 个带有安全层的 Web 项目,您将不得不复制粘贴您的代码 3 次并尝试将其与每个项目连接起来。

但是,如果您创建一个具有特定工作的项目的安全模块怎么办。通过将其注入您的应用程序,然后使用它就很容易使用它。

正如@ben75 的回答中提到的那样,一个 Maven 构建命令和构建所有使用过的 jar 的正确顺序。你不会再想哪个取决于另一个。

于 2019-03-30T22:02:39.890 回答
0

我发现 maven 模块非常有用,原因如下:

  • 架构分层和边界

例如,我制作了一个 maven 模块application-contract,其中包含我的表示层看到的接口。所以我有 UI->Presenter-> application-contract <-application-impl <- Infrastructure -> 域。这样,我知道我的表示/UI 层将无法访问我的域/应用程序层中的类。如果我在 UI 中编码时域类不在类路径中,我将无法使用它们。我喜欢这种方式(利用类路径限制)。也许 Java 9 模块也可以解决这个问题,但是(不幸的是)我使用 Java 8。

  • 每次在一个模块中运行测试

当我将代码更改为作为模块的层时(如前所述),我只能运行它的测试,而无需从我没有更改的代码中重新运行测试。这给了我速度。我的表示层测试需要大约 3 秒(300 次测试)。每次我将代码更改为 Presenter 或应用程序层以下的任何内容时,我都不希望我的数据库 H2 集成测试运行。或运行我的图像处理测试。因为这些做 IO 并且它们很慢。

  • 建造

几乎是一样的。当我将代码更改为 UI 时,我只需要构建和部署 UI 的东西(我的 UI 是在 Java 中的)。

于 2021-05-25T15:04:08.047 回答