8.6 ActiveMQ 和 JNDI
8.6 ActiveMQ and JNDISo far this chapter has demonstrated how to configure the ActiveMQ administrative objects (the ConnectionFactory and Destination objects) for each container that was covered. This entailed a style of configuration for the ConnectionFactory and Destination objects that was specific to each container so that they were made accessible via JNDI to the sample web application. The sample web application then used Spring to look up those objects via JNDI in order to interact with ActiveMQ. The following listing shows an example of the Spring JNDI lookup. |
8.6 ActiveMQ 和 JNDI到目前位置,本章内中已经阐述了如何为本章中涉及到的每一个web容器配置 ActiveMQ 的管理对象 (ConnectionFactory对象和Destination对象).这就需要一种配置方式,为每一种web容器配置 ConnectionFactory对象和Destination对象,以便容器中的示例程序可以通过JNDI来访问那两个 对象.示例web程序中使用Spring通过JNDI来查找这些对象以便能够跟ActiveMQ交互.下面的代码 清单是Spring的JNDI查找示例配置: |
... <jee:jndi-lookup id="connectionFactory" jndi-name="java:comp/env/jms/ConnectionFactory" cache="true" resource-ref="true" lookup-on-startup="true" expected-type="org.apache.activemq.ActiveMQConnectionFactory" proxy-interface="javax.jms.ConnectionFactory"> </jee:jndi-lookup> <jee:jndi-lookup id="fooQueue" jndi-name="java:comp/env/jms/FooQueue" cache="true" resource-ref="true" lookup-on-startup="true" expected-type="org.apache.activemq.command.ActiveMQQueue" proxy-interface="javax.jms.Queue"> </jee:jndi-lookup> ... |
|
The configuration in listing 8.19 uses the Spring framework to perform a JNDI lookup of the ConnectionFactory and the Destination objects. Because the JNDI provider for each application server has already been configured (see the earlier sections related to the different application servers), this simple Spring configuration is powerful— it makes easy work of performing JNDI lookups. And the sample web application was always deployed locally to the application server where the JNDI provider is running, making the JNDI lookup a local call. But what if the JMS client isn’t deployed locally to an application server? |
代码清单8.19中的配置代码使用Spring框架的JNDI来查找 ConnectionFactory对象和Destination对象. 因为每个应用程序服务器的JNDI提供者已经配置好了(参阅前面章节中的不同应用服务器相关部分),这里 的Spring 配置功能和强大,这个配置是的JNDI查找变得想到容易.同时,示例用的web程序通常会部署到 应用程序服务器中,且这些服务器中的JNDI提供者也已经在运行了,这样JNDI查找就变成了一种本地查找. 但是,假如JMS客户端没有部署到一个应用程序服务器中该如何进行JNDI查找呢? |
8.6.1 Client-side JNDI configurationAlthough the example in this chapter didn’t make use of it, ActiveMQ also provides the ability to configure a locally accessible, client-side JNDI context for retrieving JMS administrative objects. This isn’t required to be used, but is provided because JNDI is so commonly used. |
8.6.1 客户端 JNDI配置尽管本章中的示例程序没有用到客户端JNDI配置,但ActiveMQ同样提供了客户端的JNDI配置,以便 可以通过本地访问的方式获取JMS管理对象.虽然不一定非要使用这种方式,但是ActiveMQ提供这样 的功能,因为JNDI的使用太广泛了. |
An important point to understand about ActiveMQ and JNDI is that ActiveMQ doesn’t provide a remotely accessible JNDI provider—a JNDI provider where the JMS administered objects are configured on the server side and made available for remote lookup by an application running on a different host. Instead, ActiveMQ provides a simple in-memory JNDI context over a simple hash map. To configure a remotely accessible JNDI, you’ll need to use a third-party JNDI provider, for example, a Java EE container’s JNDI provider (which was shown throughout this chapter). |
要理解ActiveMQ和JNDI,比较重要的一点是,ActiveMQ 没有 供远程访问的JNDI提供者,这种 远程JNDI提供者是指JMS管理对象在服务器段配置,但是可以通过运行在远程主机上的程序来 查找JNDI资源.相反,ActiveMQ提供了一种简单的基于内存的JNDI哈希表上下文.要配置远程的JNDI 提供者,你需要使用第三方的JNDI提供者,比如,使用一个Java EE 容器的JNDI提供者(比如本章前面 内中使用过的容器). |
ACTIVEMQ JNDI SUPPORT ActiveMQ provides support for a locally accessible JNDI context on the client side. With this style of configuration, the client-side JNDI configuration makes use of a URI to access a remote ActiveMQ broker when the connection factory is created. The best way to understand this style of configuration is to review an example. |
ACTIVEMQ 的JNDI支持 ActiveMQ为客户端提供本地访问JNDI上下文支持.使用这种风格的配置,当连接工厂创建成功以后, 客户端的JNDI配置可以使用一个URI来访问远程ActiveMQ代理.理解这种配置最好的方式是通过一 个实例. |
If an ActiveMQ instance is running on host A and a Java client application is running on host B, and you want to look up a connection factory via JNDI to access the remote ActiveMQ instance from the Java application, then you need to configure a JNDI context in the Java application. An example jndi.properties file is shown next. |
假如ActiveMQ示例在主机A上运行,而一个Java 客户端程序在主机B上运行.如果主机B上的程序 打算通过JNDI访问主机A上的ActiveMQ代理,那么你需要在主机B的java程序中配置JNDI上下文. 下面是有一个jndi.properties的例子. |
# # This is an example jndi.properties file for use with ActiveMQ. To make use of # the locally available ActiveMQ JNDI provider place this file in the classpath # of the client application. # # # The java.naming.factory.initial property is a standard JNDI system # property # (http://java.sun.com/products/jndi/tutorial/beyond/env/context.html) # that is used to specify the InitialContextFactory implementation to # use. In this instance, the ActiveMQInitialContextFactory is used to # provide a locally available context factory. # java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory # # The JNDI names for the connection factories to be registered in JNDI. # These are the name that should be used to lookup the connection # factories in JNDI. # connectionFactoryNames = remotePublisherConnectionFactory, remoteConsumerConnectionFactory # # Configure the connection factory for publishers. For more information # on available properties, see the ActiveMQConnectionFactory class. # connection.remotePublisherConnectionFactory.brokerURL = tcp://hostA:61616 connection.remotePublisherConnectionFactory.username = publisher connection.remotePublisherConnectionFactory.username = password # # Configure the connection factory for consumers. For more information # on available properties, see the ActiveMQConnectionFactory class. # connection.remoteConsumerConnectionFactory.username = tcp://hostA:61616 connection.remoteConsumerConnectionFactory.username = consumer connection.remoteConsumerConnectionFactory.username = password # # Define a JMS queue destination to be registered in JNDI. The format # for specifying JMS queue is queue.<logical name> = <physical name> # where <logical name> is whatever you like and <physical name> is the # actual queue name referenced by ActiveMQ. # queue.MyTestQueue = TEST.FOO # # Define a JMS topic destination to be registered in JNDI. The format for # specifying a JMS topic is topic.<logical name> = <physical name> where # <logical name> is whatever you like and <physical name> is the actual # topic name referenced by ActiveMQ. # topic.someTopicName = GREEN.DEMO.TOPIC |
|
To use the jndi.properties file shown in listing 8.20, it must be placed in the classpath of the client application. The first property defined is the standard java.naming. factory.initial property. This is a standard system property for configuring JNDI. It’s used to note the implementation of the InitialContextFactory interface to use. The example is using the ActiveMQInitialContextFactory, so that class must be available on the classpath. |
jndi.properties文件必须要放到客户端应用程序的类路径中(classpath)以便能被用到.第一个属性 定义的是标准的 java.naming.factory.initial.这个是配置JNDI的标准系统属性,是 InitialContextFactory接口的实现类.示例的配置文件中使用的是ActiveMQInitialContextFactory 类,所以这个类必须能在类路径(classpath)中找到. |
The connectionFactoryNames property is used to specify the names of the connection factories that will be created and placed in the JNDI tree. In listing 8.20, the names remotePublisherConnectionFactory and remoteConsumerConnection- Factory were used. This means that to resolve either one of these connection factories, these two names would be used in a JNDI lookup. Here’s a snippet of the code to be used to look up one of them: |
connectionFactoryNames属性用于配置连接工厂的名称,这些连接工厂创建完成后会被放到JNDI树中. 代码清单8.20中,使用了remotePublisherConnectionFactory和remoteConsumerConnectionFactory 作为连接工厂的名称.这样意味着要想获取任何一个连接工厂,需要使用这两个名称通过JNDI查找.下面是 查找其中一个连接工厂的示例代码: |
... Context ctx = new InitialContext(); ConnectionFactory factory = (ConnectionFactory) ctx.lookup("remotePublisherConnectionFactory"); ... |
|
Each connection factory can also be configured in the jndi.properties file by specifying the property name to be set. In listing 8.20, the brokerURL, the username, and the password are being set. Numerous other properties can be set on a connection factory, so take a look at the properties available in the ActiveMQConnectionFactory class. The last items to be specified in listing 8.20 are a couple JMS destinations. The format for defining destinations is shown in the example. As you can see, the logical name has no bearing on the physical name; it’s an alias to the destination to be used when performing a JNDI lookup of the destination. Here’s a snippet demonstrating a JNDI lookup for the queue destination: |
每个连接工厂的属性都可以在 jndi.properties文件中进行配置.代码清单8.20中,设置了连接工厂的 brokerURL,username和password属性.连接工厂还有很多属性可以惊喜配置,详情可查看相关文档 中ActiveMQConnectionFactory类的可配置属性.最后,在代码清单8.20中设置的是两个JMS消息目 的地.定义消息目的地的格式请参考8.20的示例代码.正如你看到的,消息目的地的逻辑名称和物理名称 没有必然的关联,逻辑名称是使用JNDI查找消息目的地时用到的别名.下面是通过JNDI查找消息队列 的代码片段: |
... Context ctx = new InitialContext(); Queue myTestQueue = (Queue) ctx.lookup("MyTestQueue"); ... |
|
And here’s an example JNDI lookup for the topic destination: |
下面是使用JNDI查找消息主题的代码片段: |
... Context ctx = new InitialContext(); Topic myTopic = (Topic) ctx.lookup("someTopicName"); ... |
|
This client-side configuration of the locally accessible InitialContextFactory provided by ActiveMQ is powerful and useful. Its major unique quality is that it’s not remotely accessible. This is one reason why all of the previous examples utilized the JNDI provider supplied by each application server. The other reason that the application server’s JNDI provider was used is because it is a best practice to have a single system of record for the JNDI configuration. |
ActiveMQ提供的这种在客户端配置本地可访问的InitialContextFactory的功能很强大并且很有用. 其唯一的独特之处在于不支持远程调用,这也是前面章节中的示例程序都使用应用程序服务器 中JNDI提供者的一个原因. 另一个原因是,应用程序服务器中使用单独系统记录JNDI配置信息是 使用JNDI提供者最佳实践. |
微信赞赏 支付宝赞赏
本文固定链接: https://www.jack-yin.com/coding/translation/activemq-in-action/1598.html | 边城网事