Nam*_*man 4 java java-platform-module-system java-module
在为问题执行概念证明时 - JPMS ServiceLoader 对我来说并不像预期的那样工作。
在向模块路径提供 jar 与目标类时,我达到了理解两个模块如何解析的差异的状态。控制台有一个单行差异:
base.service binds user.service file://.../user-service/target/classes/
Run Code Online (Sandbox Code Playgroud)
这实际上意味着什么?在规范或概念草案中无法真正找到该术语的此类参考。
此外,在自动模块解析期间,这种行为何时会有所不同?(参考这个答案)
这很可能是指处理的绑定操作——关系。resolveAndBindusesprovides
该方法完全按照 所指定的方式工作,
resolve除了解析模块的图使用由服务-使用依赖关系引入的模块进行扩充。更具体地说,根模块就像通过调用
resolve.service dependences然后检查解析的模块以及父配置中的所有模块。给定模块查找器找到的所有模块provide,其中一种或多种服务类型的实现都被添加到模块图中,然后就像通过调用该resolve方法一样解析。将模块添加到模块图中可能会引入新的服务使用依赖关系,因此该过程迭代地工作,直到不再添加更多模块。
因此,绑定发生在解析之后,但仍然在调用相关模块的任何代码之前。即,它是否ServiceLoader在模块中实际使用并不重要。但是当它被使用时,它会利用已经可用的信息。因此,此时已经排除了许多潜在问题。这也是我们可以构建优化的模块图像预链接此类服务的原因。
但是,这不适用于自动模块,因为它们没有uses指令。没有这些信息,服务查找只能在实际使用ServiceLoader时进行,就像通过旧类路径加载的类一样。
请注意,链接问答中的问题有点不同。根据OP的信息,编译时使用了模块声明。但是,OP 使用-jar选项运行应用程序,该选项将指定的 jar 文件放在类路径上并从那里加载它,创建一个未命名的模块,而不是一个自动模块。这忽略了已编译的,module-info并且在没有老式META-INF/services/…资源的情况下,根本找不到服务实现。OP 的代码旨在在未找到任何服务时回退到默认服务实现,这与通过ServiceLoader.
您的答案的关键区别在于 start 方法-m base.service/base.service.ServiceUser,它将base.service通过模块路径定位并启动其base.service.ServiceUser,以及--add-modules …user.service,以确保将提供服务的模块添加到运行时环境中。后者是必需的,因为从启动的模块base.service到没有直接依赖关系user.service,因此它不会自动加载。
因此,在您的答案设置中,两个模块都按原样加载。当他们有一个 时module-info,它的provides指令将被处理以找到服务实现,否则,它是一个自动模块,必须有一个META-INF/services/…文件。如上所述,没有与uses自动模块的指令等效的指令,因此您永远不会看到它们的“绑定”日志条目。但他们可能仍会使用服务查找。
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |