module.a 绑定 module.b 是什么意思?
What does a module.a binds module.b mean during the resolution?
在对问题执行概念验证时 - 。
当我向模块路径提供 jar 与目标 类 时,我了解了两个模块在解析方式上的差异。控制台有一行差异:
base.service binds user.service file://.../user-service/target/classes/
这实际上意味着什么?在 spec or the conceptual draft.
中无法真正找到该术语的此类引用
此外,在自动模块解析过程中,这种行为何时会有所不同? (参考)
这很可能是指resolveAndBind
处理uses
—provides
关系的绑定操作。
This method works exactly as specified by resolve
except that the graph of resolved modules is augmented with modules induced by the service-use dependence relation.
More specifically, the root modules are resolved as if by calling resolve
. The resolved modules, and all modules in the parent configurations, with service dependences
are then examined. All modules found by the given module finders that provide
an implementation of one or more of the service types are added to the module graph and then resolved as if by calling the resolve
method. Adding modules to the module graph may introduce new service-use dependences and so the process works iteratively until no more modules are added.
因此,绑定发生在解析之后,但仍在调用相关模块的任何代码之前。也就是说,ServiceLoader
是否在模块中实际使用并不重要。但是当它被使用时,它会利用已经可用的信息。所以在这一点上已经排除了很多潜在的问题。这也是我们可以构建预链接此类服务的优化模块映像的原因。
但是,这不适用于自动模块,因为它们没有 uses
指令。如果没有这些信息,服务查找只能在实际使用 ServiceLoader
时进行,就像通过旧类路径加载 类 一样。
请注意,链接的问答中的问题有点不同。根据OP的信息,编译时使用了模块声明。但是,OP 运行 应用程序使用 -jar
选项将指定的 jar 文件放在 类路径 上并从那里加载它,创建一个 unnamed 模块,而不是自动模块。这会忽略已编译的 module-info
并且在没有老式 META-INF/services/…
资源的情况下,根本找不到任何服务实现。 OP 的代码旨在在找到 none 时回退到默认服务实现,这与通过 ServiceLoader
.
找到默认服务的场景没有区别。
你的答案的关键区别在于启动方法 -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
指令等效的指令,因此您永远不会看到它们的“绑定”日志条目。但他们可能仍会使用服务查找。
在对问题执行概念验证时 -
当我向模块路径提供 jar 与目标 类 时,我了解了两个模块在解析方式上的差异。控制台有一行差异:
base.service binds user.service file://.../user-service/target/classes/
这实际上意味着什么?在 spec or the conceptual draft.
中无法真正找到该术语的此类引用此外,在自动模块解析过程中,这种行为何时会有所不同? (参考
这很可能是指resolveAndBind
处理uses
—provides
关系的绑定操作。
This method works exactly as specified by
resolve
except that the graph of resolved modules is augmented with modules induced by the service-use dependence relation.More specifically, the root modules are resolved as if by calling
resolve
. The resolved modules, and all modules in the parent configurations, withservice dependences
are then examined. All modules found by the given module finders thatprovide
an implementation of one or more of the service types are added to the module graph and then resolved as if by calling theresolve
method. Adding modules to the module graph may introduce new service-use dependences and so the process works iteratively until no more modules are added.
因此,绑定发生在解析之后,但仍在调用相关模块的任何代码之前。也就是说,ServiceLoader
是否在模块中实际使用并不重要。但是当它被使用时,它会利用已经可用的信息。所以在这一点上已经排除了很多潜在的问题。这也是我们可以构建预链接此类服务的优化模块映像的原因。
但是,这不适用于自动模块,因为它们没有 uses
指令。如果没有这些信息,服务查找只能在实际使用 ServiceLoader
时进行,就像通过旧类路径加载 类 一样。
请注意,链接的问答中的问题有点不同。根据OP的信息,编译时使用了模块声明。但是,OP 运行 应用程序使用 -jar
选项将指定的 jar 文件放在 类路径 上并从那里加载它,创建一个 unnamed 模块,而不是自动模块。这会忽略已编译的 module-info
并且在没有老式 META-INF/services/…
资源的情况下,根本找不到任何服务实现。 OP 的代码旨在在找到 none 时回退到默认服务实现,这与通过 ServiceLoader
.
你的答案的关键区别在于启动方法 -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
指令等效的指令,因此您永远不会看到它们的“绑定”日志条目。但他们可能仍会使用服务查找。