gpt4 book ai didi

java - 为什么应用程序模块不需要提供服务的模块?

转载 作者:行者123 更新时间:2023-12-02 01:30:28 27 4
gpt4 key购买 nike

ServiceLoader.java 文档注释:

It is strongly recommended that the application module does not require modules which contain providers of the service.

为什么强烈建议这样做,如果不遵循建议会发生什么?


上下文:这间接意味着定义服务的模块不应同时导出该服务的提供者。我认为在同一模块中提供服务的默认实现会很方便。

最佳答案

为什么不需要 Provider 模块?

原因是因为 uses/provivdes 指令和java.util.ServiceLoader API 是为类似插件的架构而设计的。您可以通过控制模块路径/类路径上的提供程序来控制哪些插件可用。如果您需要 provider 模块,那么您不能再省略它,因为应用程序将由于缺少依赖项而无法启动。

文档

The documentation如果您也查看前一句话,您引用的话会更有意义,这提供了更多上下文。

In addition, if the application module does not contain the service, then its module declaration must have a requires directive that specifies the module which exports the service. It is strongly recommended that the application module does not require modules which contain providers of the service.

这是针对下面展示的具体案例。

应用模块

module app {
requires service;
}

服务模块

module service {
exports com.example.service;

uses com.example.service.Service;
}

提供者模块

module provider {
requires service;

provides com.example.service.Service with
com.example.provider.ServiceImpl;
}

以上是推荐的方法。文档所说的是,app 模块不应包含requires provider 指令。原因已经解释过了。

另请注意,这不会阻止 service 模块或 app 模块提供服务接口(interface)的默认实现。

示例模块解析

如果您为上述模块创建和编译一个实现,那么您可以在运行时通过--show-module-resolution 查看模块解析。我在下面使用 --limit-modules 来控制解析哪些模块以避免混淆模块路径。如您所见,由于 apprequires provider,因此可以省略 provider 而仍然有一个可用的应用程序。

我的服务接口(interface)有一个 getMessage() 方法,它只返回一个 String。我的主类迭代可用的提供者(如果有的话),并输出提供者的类名和“消息”。此输出出现在下面的模块分辨率输出之后,并且明显不同。

请注意,我从 Service 接口(interface)中的静态方法加载提供程序,因为 service 模块是我有 uses 指令的地方所述界面。

提供者模块

命令:

java --show-module-resolution --limit-modules app,service,provider --module-path <path> --module app/com.example.app.Main

输出:

root app <module-location>
app requires service <module-location>
service binds provider <module-location>
provider requires service <module-location>

APPLICATION OUTPUT
Provider: 'com.example.provider.ServiceImpl'
message => Hello, World!

没有提供者模块

命令:

java --show-module-resolution --limit-modules app,service --module-path <path> --module app/com.example.app.Main

输出:

root app <module-location>
app requires service <module-location>

APPLICATION OUTPUT
There are no available providers...

上一个答案

此答案的前一版本有以下示例来演示文档的内容:

服务模块

module service {
requires provider;

exports com.example.service;

uses com.example.service.Service;
}

提供者模块

module provider {
requires service;

provides com.example.service.Service with
com.example.provider.ServiceImpl;
}

不仅我对文档的目的不正确,而且由于 Java 平台模块系统 不允许在编译时循环依赖,以上甚至是不可能的。

关于java - 为什么应用程序模块不需要提供服务的模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73422270/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com