Maven Java接口与实现多模块问题

Maven Java接口与实现多模块问题,java,maven,Java,Maven,假设我有一个重用项目,包含两个模块:api和服务。重用api模块定义了其他应用程序项目可以使用的接口、类型和注释。重用服务模块包含真正的实现。重复使用项目如下所示: pom.xml: id=reuse, group=com.test.project, version=1.0.0 |__api-module |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.0}, id=reuse-api |__se

假设我有一个重用项目,包含两个模块:api和服务。重用api模块定义了其他应用程序项目可以使用的接口、类型和注释。重用服务模块包含真正的实现。重复使用项目如下所示:

pom.xml: id=reuse, group=com.test.project, version=1.0.0
|__api-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.0}, id=reuse-api
|__service-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.0}, id=reuse-srv
pom.xml: id=reuse, group=com.test.project, version=1.0.1
|__api-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.1}, id=reuse-api
|__service-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.1}, id=reuse-srv
我们的一个应用程序与重用模块有着密切的关系

pom.xml: id=application, group=com.test.project, version=2.0.0
         dependency={scope=compile, id=reuse-api, group=com.test.project, version=1.0.0}
         dependency={scope=runtime, id=reuse-srv, group=com.test.project, version=1.0.0}
问题是,如果我们现在更改了重用服务模块中的某些内容,这意味着我们更改了重用模块的实现,则必须编译整个重用模块(api和服务),并发布一个新版本,因为api和服务模块的版本与父模块不同。新的pom结构将如下所示:

pom.xml: id=reuse, group=com.test.project, version=1.0.0
|__api-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.0}, id=reuse-api
|__service-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.0}, id=reuse-srv
pom.xml: id=reuse, group=com.test.project, version=1.0.1
|__api-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.1}, id=reuse-api
|__service-module
        |__pom.xml: parent={id=reuse, group=com.test.project, version=1.0.1}, id=reuse-srv
之后,应用程序必须使用新版本的重用更改依赖关系:

pom.xml: id=application, group=com.test.project, version=2.0.1
         dependency={scope=compile, id=reuse-api, group=com.test.project, version=1.0.1}
         dependency={scope=runtime, id=reuse-srv, group=com.test.project, version=1.0.1}
是否有一种方法可以使重用服务模块的修改不会引起应用程序的更改?应用程序实际上不需要受到重用实现更改的影响,或者


你有什么意见/建议吗?谢谢。

让我们假设您的2个模块存储在某个工件存储库中(例如,您公司中托管的某些模块)

这些模块在多个应用程序中共享:

app-1
   compile: service-api-1.0.0
   runtime: service-impl-1.0.0
app-2
   compile: service-api-1.0.0
   runtime: service-impl-1.0.0
应用程序应该在build configuration()中定义您的存储库,并按版本号引用它们

每次在API/实现上完成一组更改时,都应该发布一个更高版本的库

库版本通常由3个组件组成
[major].[minor].[bugfix]

  • Bugfix
    如果没有新功能,只是对现有功能进行了修复,则应在每个版本中更新版本
  • Minor
    version在有与以前版本向后兼容的新功能时更新
  • Major
    当我们引入不兼容的更改时,版本会发生更改
例如,在修复
service-impl-1.0.0
中的一些实现缺陷时,您正在发布
service-impl-1.0.1
。此版本可能/应该仍然根据
service-api-1.0.0
进行编译

此新版本将安装在您的存储库中,然后将删除其内容

service-api-1.0.0
service-impl-1.0.0
service-impl-1.0.1
除非更新应用程序的配置,否则仍将根据存储库中仍然可用的旧版本编译和构建应用程序。因此,您现在可以:

app-1
   compile: service-api-1.0.0
   runtime: service-impl-1.0.0
app-2
   compile: service-api-1.0.0
   runtime: service-impl-1.0.1

无需更改每个应用程序,只要它们可以访问库的历史版本。仅当您希望在中获得新功能时,才可以更改依赖项版本(与maven central中其他公共共享库的操作非常相似)。

如果更改库的代码,应用程序有三种选择:

  • 使用新版本并重新编译
  • 保留旧版本,忽略所做的更改
  • 不要再次编译,而是在运行时使用新库
  • 第三个选项有点冒险,因为它要求所有接口和所有行为都保持不变,否则可能会出现运行时异常。不过,这很常见


    如果您真的想将库的实现与应用程序解耦,则需要一种不同的依赖关系,例如REST服务。实际上,这与(3)类似,因为您更改了REST服务的实现,但保证了行为和接口不变。

    如果没有更改,为什么要更改API的版本?无需更改API的版本。如果您还使用类似于Spring的框架,请配置您的bean,并使用服务定位器获取所需的bean实例。