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

2023-12-13

ServiceLoader.java 文档指出:

强烈建议应用程序模块不需要包含服务提供者的模块。

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


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


为什么不需要提供者模块?

原因是因为uses / provivdes指令和 这java.util.ServiceLoaderAPI 是为类似插件的架构而设计的。您可以通过控制模块路径/类路径上的提供程序来控制哪些插件可用。如果你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平台模块系统不允许在编译时出现循环依赖。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么应用程序模块不需要提供服务的模块? 的相关文章

  • 重构——套接字中的良好实践——简单的服务器-客户端 Swing 应用程序

    我使用单例和观察者模式编写了一个带有 Swing 接口的简单服务器 客户端程序 每个客户端都连接到服务器并可以发送消息 服务器将其收到的消息转发给其余的客户端 客户端使用 GUI 允许它们随时连接和断开与服务器的连接 该程序运行得很好 因为
  • 如何防止在 CXF Web 服务客户端中生成 JAXBElement

    我正在尝试使用 CXF 创建一个 Web 服务客户端来使用 WCF Web 服务 当我使用 wsdl2java 时 它生成具有 JAXBElement 类型而不是 String 的对象 我读到有关使用 jaxb bindings xml 文
  • 以点作为分隔符分割字符串

    我想知道我是否要在一个字符串上分割字符串 正确的方式 我的代码是 String fn filename split return fn 0 我只需要字符串的第一部分 这就是我返回第一项的原因 我问这个是因为我在 API 中注意到 意味着任何
  • 如何在数据库中对 (Java) 枚举进行建模(使用 SQL92)

    您好 我正在使用名为 性别 的列对实体进行建模 在应用程序代码中 性别应该是一个 Java 枚举类型 有 2 个值 男性和女性 知道作为数据类型的枚举不是通用 SQL 语言 92 的一部分 您将如何建模它 数据模型必须是可移植的 以便由多个
  • 空 EntityManager/EJB 注入 MDB

    我有一个消息驱动 bean MDB 部署到 WebLogic 12 1 3 我尝试使用 PersistenceContext 注释将实体管理器注入 MDB 但实体管理器为空 我还尝试注入一个简单的无状态会话 bean 它也是空的 但是 Me
  • 此版本不符合 Google Play 64 位要求,添加库后仍然出现错误

    我正在 Play 商店上传一个视频编辑器应用程序 其中包含带有一些本机代码的库 所以我通过将其添加到 gradle 来使其兼容 64 位 ndk abiFilters armeabi v7a arm64 v8a x86 x86 64 添加了
  • 更改 JTextPane 的大小

    我是Java新手 刚刚在StackOverflow中找到了这段代码 ResizeTextArea https stackoverflow com questions 9370561 enabling scroll bars when jte
  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • Java 类:匿名类、嵌套类、私有类

    有人能解释一下Java中匿名类 嵌套类和私有类之间的区别吗 我想知道与每个相关的运行时成本以及每个编译器的方法 这样我就可以掌握哪个最适合用于例如性能 编译器优化的潜力 内存使用以及其他 Java 编码人员的普遍可接受性 我所说的匿名类是指
  • 如何列出所有可用的 LookAndFeel 主题?

    如何列出所有可用的 LookAndFeel 主题 我想在 JComboBox 中显示以供用户选择 这真的很简单 public static UIManager LookAndFeelInfo getInstalledLookAndFeels
  • 膨胀类片段 InflateException 二进制 XML 文件时出错

    我正在使用 Material Design 和 NavigationDrawer 布局等设计我的第一个应用程序 但我遇到了一个问题 该应用程序非常简单 它只显示文本 并且基于 Android Studio 中提供的模板 尝试启动我的应用程序
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 在方法内声明类 - Final 关键字 [重复]

    这个问题在这里已经有答案了 给定方法中的以下内部类 IsSomething public class InnerMethod private int x public class Something private int y public
  • 使用 Cucumber Scenario Outline 处理 Excel 电子表格

    如果可能的话 我试图找到一种更优雅的方法来处理从与 Excel 电子表格行 第 n 个 相关的 Cucumber Scenario Outline 中调用第 n 个数字 目前 我正在使用迭代编号来定义要从中提取数据的 Excel 电子表格的
  • java中wav文件转换为字节数组

    我的项目是 阿塞拜疆语音的语音识别 我必须编写一个程序来转换wav文件到字节数组 如何将音频文件转换为byte 基本上如第一个答案中的片段所描述 但不是BufferedInputStream use AudioSystem getAudio
  • 如何使用maven创建基于spring的可执行jar?

    我有一个基于 Maven 的 Spring WS 客户端项目 我想将其打包为单个 jar 在eclipse中 一切运行正常 当我尝试将其打包为可执行 jar 时 我收到 ClassNotFound 异常 因为 Spring jar 未包含在
  • 无法在 BlackBerry Playbook 上设置音量

    我在更改黑莓游戏书的音量时遇到问题 首先 我将 Android 应用程序重新打包到 Palybook 应用程序 我需要使用搜索栏更改黑莓剧本的音量 并在搜索监听器中设置音频管理器音量 这是代码 audioManager AudioManag
  • SWT - 与操作系统无关的获取等宽字体的方法

    SWT 有没有一种方法可以简单地获得跨各种操作系统的等宽字体 例如 这适用于 Linux 但不适用于 Windows Font mono new Font parent getDisplay Mono 10 SWT NONE 或者我是否需要
  • C/C++ 通过 Android NDK 在 JNI 中看不到 Java 方法

    我正在尝试从使用 NDK 构建的 C 类文件调用 Java 方法 它不断抛出常见的 未找到非静态方法 错误并导致整个 Android 应用程序崩溃 下面的代码片段 有些东西可能不需要 但我按原样保留它们 因为焦点 问题在于refreshJN
  • 编译时在代码中替换Java静态最终值?

    在java中 假设我有以下内容 fileA java class A public static final int SIZE 100 然后在另一个文件中我使用这个值 fileB java import A class b Object t

随机推荐

  • 如何保持 Google Chrome 扩展弹出窗口打开?

    如果我打开扩展程序弹出窗口 那么我会打开另一个窗口或选项卡 如果我返回弹出窗口 则弹出窗口不会保持打开状态 有没有办法强制它使弹出窗口保持打开状态 As a user 您目前无法强制弹出窗口保持打开状态 这是 UI 团队做出的 UI 决定
  • 使 my_average(a, b) 与定义了 f_add 和 d_div 的任何 a 和 b 一起使用。以及内置函数

    简而言之 我想要的是我编写的大多数数学函数 例如 my average a b 与任何a and b其中一个f add and f div已被定义 不过载 和 且不中断my average built in type built in ty
  • 根据组中唯一/不同值的数量创建二进制变量

    我有数据如下 userID lt c 1 1 1 2 2 2 3 3 3 product lt c a a a b b c a b c df lt data frame userID product 对于每个 userID 我想创建一个二进
  • file_get_contents():SSL 操作失败,代码为 1(证书验证失败)

    我已经安装了 WAMP 3 0 4 并尝试编写一个连接到外部 HTTPS Web 服务的 PHP 脚本 但这会返回错误 警告 file get contents SSL 操作失败 代码为 1 OpenSSL 错误消息 错误 14090086
  • .NET 阻塞套接字读取直到 X 字节可用?

    假设我通过 TCP 实现了简单的协议 其中每条消息由以下部分组成 An int表示数据长度 二进制数据 长度在 1 中指定 读这样的消息我想要这样的东西 int length input ReadInt byte data input Re
  • Three.js - 用于碰撞检测的精确光线投射

    我正在使用 Three js 版本68 我使用与此人在这里使用的相同的方法进行碰撞检测 这在大多数情况下都很棒 向作者表示深深的 感谢 http stemkoski github io Three js Collision Detectio
  • Python 3 虚拟环境问题

    我遇到了类似的问题这个帖子 但我已经在运行最新版本的virtualenv我也得到了不同的ImportError 使用 virtualenv 版本 2 7 默认 工作正常 但我需要将 python3 用于另一个项目 我安装它使用brew in
  • 根据对象中键的值对数组中的对象进行分组

    我有以下数据 我想根据日期进行排序 不包括时间戳 NOTE 我可以访问moment为了这个任务 我的数据如下所示 const data fixture AC v Inter kickOffTime 2018 06 14T15 00 00Z
  • 根据分隔符分多列打印文件

    这似乎是一个简单的任务 但是使用 duckduckgo 我无法找到一种方法来正确地完成我想要做的事情 主要问题是 如何使用分隔符将 linux 或 bash 中命令的输出拆分为多列 我有一个如下所示的文件 这只是一个简化的示例 Some d
  • java8中列表的迭代列表[重复]

    这个问题在这里已经有答案了 我想知道 我们如何使用 Java 8 中的流 API 迭代多级列表 例如 List
  • PyQt 自定义小部件未显示

    我是 PyQt 的新手 我试图将 QTableView 放入一个类中 这样我就可以在类中定义它的行为 而无需将其与所有其他代码混合 但是当我这样做时 它就不会显示 这是我正在学习的代码 这是借来的 使用 QAbstractTableMode
  • 如何只读取文本文件的部分内容?

    我有一个 PHP 脚本 可以大量处理大型文本文件 主要是日志文件 问题是大多数时候我只想要它的一部分 从一个分割点到另一个分割点 但必须读取 2GB 文本文件才能获取其中的一小部分 这会减慢该过程 有什么方法可以只读取部分文本 而不必将整个
  • 使用 XmlSerializer 列表反序列化为字典

    我通过将 Dictionary 转换为 List 将数据序列化为 xml 序列化没问题 是否可以在反序列化时填充字典 现在我在反序列化完成并返回列表后填充字典 Serializable public class Attribute publ
  • 查询逗号分隔的 id 到逗号分隔的值

    我有2张桌子 部门 ID Dept 1 HR 2 Accts 3 IT Employee ID Name Depts 1 Kevin 2 1 2 Michelle 1 3 Troy 1 3 4 Rheesa 2 3 1 我正在使用 SQL
  • 有没有办法在一段时间后动态删除表中的一行?

    我试图在创建行 12 小时后从表中删除一行 我的表中有一个 dateTime 列 记录了它的创建时间 有没有办法在 12 小时后动态删除一行 这造成的另一个问题是日期可能在 12 小时内发生变化 这可能会使行的时间戳变得无关紧要 我尝试从类
  • 在 F# 中使用“内联”

    The inline在我看来 F 中的关键字与我习惯的用途有些不同 例如C 例如 它似乎会影响函数的类型 什么是 静态解析类型参数 不是所有 F 类型都是静态解析的吗 我应该什么时候使用inline功能 The inline关键字指示函数定
  • 如何使用ajax和jquery更新特定的div

    我在现场工作 那里有一个铁轨 想想 gmail 框架 就像 gmail 应用程序一样 我只想在单击导航栏上的链接时更新内部 div 我已经得到了它 所以 div 发生了变化 但它肯定没有给我我所希望的结果 这是我所拥有的的一个粗略轮廓 di
  • 更新后无法同时运行多个Android模拟器

    在 SDK Manager 中安装更新之前 它运行良好 但是我无法同时运行两个模拟器 这个问题有什么解决办法吗 我也遇到过同样的问题 为了解决这个问题 我创建了新的 AVD 并尝试运行它 OR emulator arm avd
  • Spring Security 6 CustomAuthenticationFilter(打算替换UsernamePasswordAuthenticationFilter)不起作用

    引用https www baeldung com spring security extra login fields 我打算自定义 Spring security Authentication UsernamePasswordAuthen
  • 为什么应用程序模块不需要提供服务的模块?

    ServiceLoader java 文档指出 强烈建议应用程序模块不需要包含服务提供者的模块 为什么强烈建议这样做 如果不遵循建议会发生什么 上下文 这间接意味着定义服务的模块不应该导出该服务的提供者 我认为在同一模块中提供服务的默认实现