【问题标题】:JMS connection from Java SE来自 Java SE 的 JMS 连接
【发布时间】:2019-10-26 06:54:46
【问题描述】:

我想以 代理无关 方式从 Java SE 应用程序创建 JMS 连接。

我将 JDBC 与其用于数据库连接的 URL 方案进行比较。这创建了与实际实现的独立性。

对于 JMS,我还没有找到类似的东西。我知道在 Java EE 中 JNDI 将扮演这个角色,但这是 Java SE。

我不想将我的代码绑定到任何特定的队列代理,因为我的需求是非常简单的 JMS 1.1 发送/接收文本消息。

我也看过 Spring Boot,因为它通常擅长提供某种程度的不可知论。但即使使用 Spring Boot,我也看不到这种可能性。

【问题讨论】:

    标签: java jms spring-jms


    【解决方案1】:

    JNDI 您编写 JMS 应用程序以与代理无关的方式进行连接的方式。 JNDI 客户端类是 Java SE 的一部分。 Spring 和非 Spring Java SE 应用程序都使用 JNDI 进行这种集成。

    任何 JMS 实现还应该提供可以插入到您的应用程序中的 JNDI 实现。通常这是通过在您的类路径上放置一个名为jndi.properties 的文件并将您正在使用的任何JNDI 实现的正确配置放入该文件来完成的。当您创建一个空的InitialContext 时,您的类路径上的jndi.properties 文件会被自动读取。 jndi.properties 中的 key=value 对被放入 InitialContext 中,因此当您执行查找时,一切都与您选择的实现一起工作。如果您愿意,您还可以通过a constructorInitialContext 提供特定于实现的详细信息,以编程方式进行配置。

    通过在您的 Java SE 应用程序中同时使用 JMS 和 JNDI API 并将特定于代理的连接详细信息外部化到您的 jndi.properties 文件中,您可以有效地将您的应用程序与特定于代理的代码隔离开来,这样您就可以部署您的应用程序并使用不同的在属性文件中进行一些简单更改的代理。

    JNDI 客户端实现将来自提供 JMS 实现的任何人。 JNDI 客户端本质上是以封装在 jar 中的 javax.naming.spi.InitialContextFactory 实现的形式出现的,并且通常有描述可用属性的文档。

    这里有几个例子:

    • ActiveMQ 5.x 代理在其activemq-client-<version>.jar 中提供org.apache.activemq.jndi.ActiveMQInitialContextFactory。文档可用here
    • ActiveMQ Artemis 代理在其artemis-jms-client-<version>.jar 中提供org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory。文档可用here

    明确地说,JMS 规范不要求使用 JNDI 来查找管理对象,但它建立了 约定期望 JMS 提供者会这样做。 JMS 1.1 规范的第 4.2 节规定:

    尽管受管理对象的接口不明确依赖于 JNDI,但 JMS 建立了 JMS 客户端通过使用 JNDI 在名称空间中查找它们来找到它们的约定。

    后来它说:

    预计 JMS 提供者将提供管理员在 JNDI 名称空间中创建和配置管理对象所需的工具。管理系统 管理对象的提供者实现应该是 javax.naming.Referenceable 和 java.io.Serializable ,以便它们可以存储在所有 JNDI 命名上下文中。

    根据我的经验,JMS 提供商通常渴望提供 JNDI 实现,因为如果没有它,它们将没有竞争力,因为任何替代解决方案都不符合标准,并且会迫使用户实现不可移植的代码。

    如果您遇到不提供 JNDI 实现的提供程序,您可以按照 ActiveMQ 5.xActiveMQ ArtemisQpid JMS 使用的相同模式实现自己的提供程序。这 3 个实现仅在客户端,并且基于提供给 InitialContext 的配置简单地实例化管理对象。大部分代码都是样板代码,不是很简单。

    【讨论】:

    • 知道了。但是JNDI Provider 是从哪里来的呢?这不是假设每个 JMS Provider 库都附带 JNDI Provider 吗?真的是这样吗? (假设 JNDI Provider 通常是嵌入在 Java EE 服务器中的东西)。
    • 是的,我相信 Amazon SQS 不提供实例化 ConnectionFactory 的 JNDI 方式。据我所知,JMS 提供者使用 JNDI 不是强制性的,或者至少 JMS 规范不使用 MUST 这个词。
    • 我更新了我的答案以解决您的评论。除了 JNDI 之外,没有其他选择以与代理无关的方式进行连接。
    猜你喜欢
    • 2012-08-02
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多