来自 Java SE 的 JMS 连接

JMS connection from Java SE

我想以 broker-agnostic 方式从 Java SE 应用程序创建 JMS 连接。

我正在比较 JDBC 的 URL 数据库连接方案。这创造了与实际实施的独立性。

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

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

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

JNDI 编写 JMS 应用程序以 broker-agnostic 方式连接的方式。 JNDI 客户端 类 是 Java SE 的一部分。 Spring 和 non-Spring Java SE 应用程序都使用 JNDI 进行此类集成。

任何 JMS 实现还应该提供可以插入您的应用程序的 JNDI 实现。通常,这是通过将名为 jndi.properties 的文件放置在类路径中并将适合您正在使用的 JNDI 实现的正确配置放入该文件中来完成的。当你创建一个空的 InitialContext the jndi.properties file on your classpath is read automatically. The key=value pairs in jndi.properties are put into the InitialContext so that when you perform a lookup everything works with the implementation you've chosen. You can also configure this programmatically if you like by supplying the implementation specific details to the InitialContext via a constructor.

通过在您的 Java SE 应用程序中同时使用 JMS 和 JNDI API 并将 broker-specific 连接详细信息外部化到您的 jndi.properties 文件中,您可以有效地将您的应用程序与 broker-specific 代码,以便您可以部署您的应用程序并与不同的经纪人合作,只需在属性文件中进行一些简单的更改。

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

这里有几个例子:

  • 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 用于 look-up 管理对象,但它建立了 约定 期望 JMS 提供程序将这样做。 JMS 1.1 规范的第 4.2 节指出:

Although the interfaces for administered objects do not explicitly depend on JNDI, JMS establishes the convention that JMS clients find them by looking them up in a namespace using JNDI.

然后它说:

It is expected that JMS providers will provide the tools an administrator needs to create and configure administered objects in a JNDI namespace. JMS provider implementations of administered objects should be both javax.naming.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts.

根据我的经验,JMS 提供商通常急于提供 JNDI 实现,因为如果没有它,他们将没有竞争力,因为任何替代解决方案都不符合标准,并且会迫使用户实现 non-portable 代码.

如果您 运行 进入不提供 JNDI 实现的提供程序,您可以按照 ActiveMQ 5.x, ActiveMQ Artemis, and Qpid JMS 使用的相同模式实现自己的提供程序。这 3 个实现仅为 client-side,并且根据提供给 InitialContext 的配置简单地实例化管理对象。大部分代码都是样板代码,不是的代码非常 straight-forward.