在初始化期间,客户端应用程序将需要访问 ConnectionFactory 和 Destination(Queue 和 Topic 的基本类型)对象。这些类型统称为受管对象,JMS 规范规定它们应实现javax.naming.Referenceable 和java.io.Serializable 接口。
这意味着您不仅可以通过命名服务,还可以通过其他机制使受管对象对客户端可用。例如,您可以序列化管理对象并将它们存储在文件中,将序列化对象作为电子邮件的附件传输,使.jso(Java 序列化对象)文件在 Web/FTP 服务器上可用,等等。如果您担心 Extranet 客户端不知道您的内部命名服务的详细联系信息,这种方法可能会很有用。
但这并不能真正回答您的问题:哪个是使受管对象对 JMS 客户端可用的最佳技术?命名服务?共享文件系统上的序列化对象文件?网络或 FTP 服务器?数据库?答案是没有“普遍最佳”的方式。一些组织将标准化使用一种技术,而其他组织则更喜欢使用另一种技术。如果您正在编写一个将在许多组织中使用的 JMS 客户端,那么您可以让您的客户端灵活地访问受管理对象。您可以通过实现具有如下签名的方法来做到这一点:
public Object importObject(String instructions);
该方法的实现应该查看instructions 的开头,以确定它应该使用哪种技术来检索对象。例如:
obj1 = importObject("naming#path/in/naming/service");
obj2 = importObject("file#path/to/file.jso");
obj3 = importObject("exec#command to execute");
(实际上,指令应该从命令行参数或配置文件中获取,而不是硬编码到应用程序中。)
上面显示的"exec#..." 变体可以执行任意shell 命令,该命令可以从Web 或FTP 服务器(可能使用curl)、数据库或任何最方便的方式检索.jso 文件用户。多年前,我为另一种中间件技术 (CORBA) 编写了一种类似的实用函数,它提供的灵活性被证明是非常有用的。你可以阅读一下我的 CORBA 实用函数here。
另一个需要注意的问题(@skaffman 在评论中提到的一个问题)是,虽然 JMS 规范定义了一个 API,但它确实没有定义了一个在线协议。因此,不同 JMS 产品之间通常没有互操作性。因此,如果您的公司内部 JMS 应用程序是使用产品 X 构建的,那么公司外部 JMS 客户端也需要使用产品 X 构建。话虽如此,一些供应商可能会出售可以通过以下方式接收传入消息的“桥接器”产品 X 使用的在线协议,然后使用产品 Y 的在线协议重新传输消息。这是提供不同 JMS 产品之间互操作性的一种方式。
免责声明:不要让这个答案的冗长欺骗您以为我是 JMS 专家。实际上我使用 JMS 的经验非常有限,所以如果有人添加评论说我的建议有缺陷,那么他们可能是对的。