为什么不需要提供者模块?
原因是因为uses
/ provivdes
指令和
这java.util.ServiceLoader
API 是为类似插件的架构而设计的。您可以通过控制模块路径/类路径上的提供程序来控制哪些插件可用。如果你requires
提供程序模块,那么您不能再省略它,因为应用程序将由于缺少依赖项而无法启动。
文档
文档如果你也看看前面的句子,你引用的内容会更有意义,它提供了更多的上下文。
另外,如果应用程序模块不包含服务,那么它的模块声明必须有一个requires指定导出服务的模块的指令。强烈建议应用程序模块这样做not需要包含服务提供者的模块。
这是针对下面演示的具体案例。
应用模块
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
module 不应该包括一个requires provider
指示。原因已经解释过了。
另请注意,这并不会阻止service
模块或app
模块提供服务接口的默认实现。
模块分辨率示例
如果您创建并编译上述模块的实现,那么您可以通过以下方式在运行时查看模块解析--show-module-resolution
. I use --limit-modules
下面来控制解析哪些模块,以避免弄乱模块路径。正如你所看到的,自从app
才不是requires provider
, 可以省略provider
并且仍然有一个有效的应用程序。
我的服务接口有一个getMessage()
方法只返回一个String
。我的主类迭代可用的提供程序(如果有),并输出提供程序的类名和“消息”。该输出出现在下面的模块分辨率输出之后,并且与下面的模块分辨率输出明显不同。
注意我从静态方法加载提供程序Service
接口,因为service
模块是我拥有的uses
所述接口的指令。
带提供者模块
Command:
java --show-module-resolution --limit-modules app,service,provider --module-path <path> --module app/com.example.app.Main
Output:
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!
没有提供者模块
Command:
java --show-module-resolution --limit-modules app,service --module-path <path> --module app/com.example.app.Main
Output:
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平台模块系统不允许在编译时出现循环依赖。