来自JavaSE的JMS连接

来自JavaSE的JMS连接,java,jms,spring-jms,Java,Jms,Spring Jms,我希望以代理无关的方式从JavaSE应用程序创建JMS连接 我将用数据库连接的URL方案与JDBC进行比较。这将创建与实际实现无关的独立性 对于JMS,我还没有找到类似的东西。我知道在JavaEE中,JNDI将完成这个角色,但这是JavaSE 我不想将我的代码绑定到任何特定的队列代理,因为我的需求是非常简单的JMS 1.1文本消息发送/接收 我也看过SpringBoot,因为它通常擅长提供某种程度的不可知论。但即使使用Spring Boot,我也看不到这种可能性。JNDI是您编写JMS应用程序的

我希望以代理无关的方式从JavaSE应用程序创建JMS连接

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

对于JMS,我还没有找到类似的东西。我知道在JavaEE中,JNDI将完成这个角色,但这是JavaSE

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

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

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

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

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

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

以下是几个例子:

  • ActiveMQ 5.x代理提供了
    org.apache.ActiveMQ.jndi.ActiveMQInitialContextFactory
    ,可在其
    ActiveMQ客户端-.jar
    中找到。有文件可供查阅
  • ActiveMQ Artemis代理提供
    org.apache.ActiveMQ.Artemis.jndi.ActiveMQInitialContextFactory
    ,可在其
    Artemis jms客户端-.jar
    中找到。有文件可供查阅
明确地说,JMS规范不要求使用JNDI来查找管理对象,但它建立了JMS提供者将这样做的约定和期望。JMS 1.1规范第4.2节规定:

尽管受管对象的接口并不显式依赖于JNDI,但JMS建立了一种约定,即JMS客户机通过使用JNDI在名称空间中查找它们来找到它们

后来它说:

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

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


如果您遇到一个不提供JNDI实现的提供程序,您可以按照和使用的相同模式实现自己的JNDI实现。这3种实现仅为客户端实现,仅根据提供给
InitialContext
的配置实例化管理对象。大部分代码都是锅炉板,而不是很直接。

明白了。但是JNDI提供者来自哪里?这不是假设每个JMS提供程序库中都有JNDI提供程序吗?真的是这样吗?(考虑到JNDI提供者通常是嵌入JavaEE服务器的东西)是的,我相信AmazonSQS不会提供JNDI方式来实例化
连接工厂。据我所知,JMS提供者使用JNDI不是强制性的,或者至少JMS规范没有使用MUST这个词。我更新了我的答案以回应您的评论。除了JNDI之外,没有其他选项可以以代理不可知的方式进行连接。