简体   繁体   English

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

[英]Maven Java interface and implementation multi-module issue

Let's say I have a re-use project with 2 modules: api and service.假设我有一个包含 2 个模块的重用项目:api 和服务。 The re-use api module defines interfaces, types, annotations that can be used by other application projects. re-use api 模块定义了可以被其他应用程序项目使用的接口、类型、注解。 The re-use service module contains the real implementation.重用服务模块包含真正的实现。 The re-use project looks like this:重用项目如下所示:

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

And one of our applications has a depdency to the re-use module.我们的一个应用程序依赖于重用模块。

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}

The thing is, if now we change something in the re-use service module, meaning we change the implimentation of the re-use module, the whole re-use module(api and service) has to be compiled and a new version will be released, because the versions of the api and the service module inherict from the parent module.问题是,如果现在我们更改重用服务模块中的某些内容,这意味着我们更改重用模块的实现,则必须编译整个重用模块(api 和服务),并且新版本将是发布,因为api和服务模块的版本是从父模块继承的。 The new pom structure will look like this:新的 pom 结构将如下所示:

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

After that, the application has to change the dependency with the new version of re-use:之后,应用程序必须使用新版本的重用更改依赖项:

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}

Is there a way that the modification of re-use service module will not cause a change also to the application?有没有办法使重用服务模块的修改也不会导致应用程序发生变化? The application does not really need to be affected by the change of the re-use implementation or?应用程序真的不需要受到重用实现的变化的影响吗?

Do you have some comments/suggestions?你有什么意见/建议吗? Thank you.谢谢你。

Lets assume that you have your 2 modules stored in some artifact repository (for example some repository manager hosted in your company)假设您将 2 个模块存储在某个工件存储库中(例如,您公司中托管的某个存储库管理器

service-api-1.0.0
service-impl-1.0.0

There modules are shared across several applications:这些模块在多个应用程序之间共享:

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

The applications should define your repository in build configuration ( additional maven repository ) and reference them by version number.应用程序应在构建配置中定义您的存储库( 附加 Maven 存储库)并按版本号引用它们。

Every time you complete a set of changes on your API/implementation you should release a library with a higher version.每次在 API/实现上完成一组更改时,您都应该发布一个具有更高版本的库。

Library version usually consist out of 3 components [major].[minor].[bugfix]库版本通常由 3 个组件组成[major].[minor].[bugfix]

  • Bugfix version should be updated each release when there are no new features but just fixes to existing functionality. Bugfix时,有没有新的功能,但只是修复现有功能的版本应该更新每一个版本。
  • Minor version is updated when there are new features that are backward compatible with the previous release.当有向后兼容以前版本的新功能时,会更新Minor版本。
  • Major version is changed when we introduce incompatible changes.当我们引入不兼容的更改时, Major版本会更改。

Eg when fixing some implementation defects in service-impl-1.0.0 you are releasing service-impl-1.0.1 .例如,在修复service-impl-1.0.0一些实现缺陷时,您正在发布service-impl-1.0.1 This one may/should be still compiled against service-api-1.0.0 .这个可能/应该仍然针对service-api-1.0.0编译。

This new version will be installed in your repository, then its contents will be这个新版本将安装在您的存储库中,然后其内容将是

service-api-1.0.0
service-impl-1.0.0
service-impl-1.0.1

Unless you update the configuration of your application it will still be compiled and build against the older version still available in your repository.除非您更新应用程序的配置,否则它仍将针对存储库中仍然可用的旧版本进行编译和构建。 So you can have now:所以你现在可以拥有:

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

There is no need to change each application as long as they have access to historical versions of your library.只要它们可以访问您的库的历史版本,就无需更改每个应用程序。 You change the dependency version only when you want to get new features in (very much the same way you do about any other public shared library in maven central).仅当您想要获得新功能时才更改依赖项版本(与您对 Maven 中心中的任何其他公共共享库所做的方式非常相似)。

If you change the code of your library, the application has three choices:如果您更改库的代码,应用程序有三个选择:

  1. Use the new version and compile again.使用新版本重新编译。
  2. Stay with the old version and ignore the changes made.保留旧版本并忽略所做的更改。
  3. Do not compile again but use the new library at runtime.不要再次编译,而是在运行时使用新库。

The third option is a bit risky because it requires all interfaces and all behaviour to be unchanged, otherwise you might get runtime exceptions.第三个选项有点冒险,因为它要求所有接口和所有行为都保持不变,否则您可能会遇到运行时异常。 It is pretty common, though.不过,这很常见。

If you really want to decouple the implementation of the library from the application, you need a different kind of dependency, eg a REST service.如果您真的想将库的实现与应用程序分离,您需要一种不同类型的依赖项,例如 REST 服务。 In the effect, this is similar to (3) because you change the implementation of the REST service but guarantee that the behaviour and interface is unchanged.在效果上,这类似于(3),因为您更改了 REST 服务的实现,但保证行为和接口不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM