【问题标题】:Sharing common code between multiple spring boot APIs在多个 Spring Boot API 之间共享通用代码
【发布时间】:2019-12-13 18:15:45
【问题描述】:

我有两个 Spring Boot REST API,它们都有完全相同的 /health 端点,我想将这个端点提取到其他 Java 项目中。

我想要以下东西:

  1. 当我编译任何 API 时,应该编译通用模块

  2. 我正在使用 docker 容器在单独的 docker 中运行这些 API。如何将通用代码的 jar 文件复制到 Docker 中。

如果这个问题看起来很愚蠢,请忽略,我不确定是将公共项目作为模块还是将其作为依赖项注入这两个项目的 pom 文件中。

【问题讨论】:

  • 这不是一个坏问题。

标签: java maven microservices pom.xml dry


【解决方案1】:

Maven 可以完成这项任务。

我想要以下东西:

当我编译任何 API 时,应该编译公共模块

Maven 多模块 pom(也称为聚合器 pom)实现了这一点。

1) 在构建方面耦合三个组件

- api-parent(如果需要,也可以使用多模块 pom 和父 pom) | |____ 通用库 (jar) |____ api-foo (spring boot fat jar) |____ api-bar (spring boot fat jar)

这种方法的缺点是common-lib的版本对于使用它的两个api模块来说必然是相同的。但是,既然您想在任何 api 的每次构建中编译 common-lib,最后这才有意义。

当您希望/需要您的 api 之间的 common-lib 版本相同时,您可以使用这种方法。如果后来发现您的 api 使用的 common-lib 的版本应该不同,因为它们没有相同的生命周期,您可以将它们解耦,如下所示。

2) 在构建方面解耦三个组件

在同一层,定义common-lib项目和两个api项目,并在每个api项目中定义一个对common-lib的依赖。

- 通用库(jar) - api-foo (spring boot fat jar) | |____使用___ common-lib v1 (jar) - api-bar (spring boot fat jar) | |____使用___ common-lib v2 (jar)

我正在使用 docker 容器在单独的 docker 中运行这些 API。 如何将通用代码的jar文件复制到Dockers中。

您不会自己复制此库。 spring boot maven 插件为您创建了包含您声明的所有依赖项以及微服务所需的 fat jar。因此,只需将 Spring Boot 创建的 jar 部署到 docker 容器上即可。

旁注:

在这两种方法中,我认为您应该在同一个 SCM 存储库中定义这三个项目(单存储库方法而不是多存储库方法),因为这三个组件在功能上是耦合的。您可能希望同时处理所有这些问题。

【讨论】:

  • 很好的答案大卫,方法 2 似乎真的很吸引人。你在 pom.xml 中对 api-foo 和 common-lib 有什么设想
  • 谢谢。有什么变化?不确定得到它:)
  • 目前我已经在 api-foo 的 pom 文件中添加了 common-lib 作为依赖项,例如: groupcommon-lib0.0.1
  • 这很好。我想目前其他 api 也是一样的。如果你的问题呢?
【解决方案2】:

您可以结合使用 maven 和构建服务器(Jenkins 等)以及巧妙的管道。将您的共同依赖项作为一个模块,并且每当您开始构建您的 REST 项目之一时,应该会发生以下情况:

  • 作为管道的一部分开始构建您的公共依赖项(我认为是下游工作)
  • 将最新版本部署到您的 maven 存储库
  • 为您在 REST 管道中的依赖项执行 maven force 版本更新(使用 mvn versions:use-latest-releases -Dincludes=groupId:artifactId),这将更新您的 REST 模块的 pom
  • 将 REST 模块的最新 pom 推送到 git

如果您想仔细管理重大更改,则对模块进行版本控制变得很重要,否则您可以摆脱 SNAPSHOTS

【讨论】:

  • 是的,这绝对是 maven 的工作!但是在复杂的项目中,代码重用成为团队应该花费适当时间思考的事情。示例:很多时候健康检查只有一行代码:返回 200 代码。但是,如果某些开发人员还想包括数据库连接检查怎么办?应该是强制执行的最佳实践还是只是一个例外?而且,对于第一种情况,如何处理从以前的做法迁移到新的做法,从 healthcheck 包更新依赖项?
  • 我明白了,也许问题是这个功能有多普遍?我认为拥有一个通用库的原因之一是全面共享经验。在您的场景中,听起来像实现 HealthAggregator 更合适。有了它,您可以实现一个通用的HealthIndicator 并允许每个团队实现自己的“HealthIndicator”,而 HealthAggregator 可以将所有检查合并到一个输出中
  • 是的,我喜欢“共享经验”的定义
猜你喜欢
  • 2012-11-11
  • 2011-04-14
  • 2022-01-15
  • 2022-01-08
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
相关资源
最近更新 更多