Toa*_*ast 2 java serviceloader java-18
ServiceLoader.java 文档指出:
强烈建议应用程序模块不需要包含服务提供者的模块。
为什么强烈建议这样做,如果不遵循建议会发生什么?
上下文:这间接意味着定义服务的模块不应该导出该服务的提供者。我认为在同一模块中提供服务的默认实现会很方便。
原因是uses/provivdes指令和java.util.ServiceLoaderAPI 是为类似插件的架构而设计的。您可以通过控制模块路径/类路径上的提供程序来控制哪些插件可用。如果您使用requires提供程序模块,则不能再省略它,因为应用程序将由于缺少依赖项而无法启动。
如果您也查看前一句话,您引用的文档会更有意义,它提供了更多上下文。
此外,如果应用程序模块不包含该服务,则其模块声明必须有一个requires指令来指定导出该服务的模块。强烈建议应用程序模块不需要包含服务提供者的模块。
这是针对下面演示的具体案例。
应用模块
module app {
requires service;
}
Run Code Online (Sandbox Code Playgroud)
服务模块
module service {
exports com.example.service;
uses com.example.service.Service;
}
Run Code Online (Sandbox Code Playgroud)
提供者模块
module provider {
requires service;
provides com.example.service.Service with
com.example.provider.ServiceImpl;
}
Run Code Online (Sandbox Code Playgroud)
以上是推荐的方法。文档所说的是app模块不应包含requires provider指令。原因已经解释过了。
另请注意,这不会阻止service模块或app模块提供服务接口的默认实现。
如果您创建并编译上述模块的实现,那么您可以在运行时通过--show-module-resolution. 我使用--limit-modules下面的方法来控制解析哪些模块,以避免弄乱模块路径。正如您所看到的,由于appdoes not requires provider,因此可以省略provider并且仍然有一个可用的应用程序。
我的服务接口有一个getMessage()方法,它只返回一个String. 我的主类迭代可用的提供程序(如果有),并输出提供程序的类名和“消息”。该输出出现在下面的模块分辨率输出之后,并且与下面的模块分辨率输出明显不同。
注意我从接口中的静态方法加载提供程序Service,因为service模块是我拥有uses所述接口的指令的地方。
带提供者模块
命令:
java --show-module-resolution --limit-modules app,service,provider --module-path <path> --module app/com.example.app.Main
Run Code Online (Sandbox Code Playgroud)
输出:
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!
Run Code Online (Sandbox Code Playgroud)
没有提供者模块
命令:
java --show-module-resolution --limit-modules app,service --module-path <path> --module app/com.example.app.Main
Run Code Online (Sandbox Code Playgroud)
输出:
root app <module-location>
app requires service <module-location>
APPLICATION OUTPUT
There are no available providers...
Run Code Online (Sandbox Code Playgroud)
该答案的前一版本使用以下示例来演示文档的内容:
服务模块
module service {
requires provider;
exports com.example.service;
uses com.example.service.Service;
}
Run Code Online (Sandbox Code Playgroud)
提供者模块
module provider {
requires service;
provides com.example.service.Service with
com.example.provider.ServiceImpl;
}
Run Code Online (Sandbox Code Playgroud)
我不仅对文档的目的不正确,而且上述内容甚至是不可能的,因为Java 平台模块系统不允许在编译时出现循环依赖。
| 归档时间: |
|
| 查看次数: |
360 次 |
| 最近记录: |