Geronimo
ActiveMQ Classic 是 Apache Geronimo 中的預設 JMS 提供者。
ActiveMQ Classic 可以同時作為 JMS 用戶端和 JMS Broker 使用。這篇簡短的
文章說明如何在獨立用戶端上使用它,以存取
遠端 Geronimo/ActiveMQ Classic Broker 上設定的主題/佇列。
1) 在 ActiveMQ Classic Broker 上設定佇列和主題
如果您使用的是獨立的 ActiveMQ Classic Broker,那麼遵循
ActiveMQ Classic 網站上的說明應該就足以設定所有內容。
但是,如果您的 ActiveMQ Classic 實例嵌入在 J2EE Geronimo
應用程式伺服器中,建立佇列和主題是將資源
配接器部署到您的 Geronimo 伺服器。
以下部署描述符可用於部署兩個主題和一個
ConnectionFactory:weatherTopic 和 weatherRequestsTopic
<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector"
version="1.5"
configId="weather/Topics"
parentId="org/apache/geronimo/SystemJMS">
<resourceadapter>
<resourceadapter-instance>
<resourceadapter-name>ActiveMQ Classic RA</resourceadapter-name>
<config-property-setting name="ServerUrl">tcp://127.0.0.1:61616</config-property-setting>
<config-property-setting name="UserName">geronimo</config-property-setting>
<config-property-setting name="Password">geronimo</config-property-setting>
<workmanager>
<gbean-link>DefaultWorkManager</gbean-link>
</workmanager>
</resourceadapter-instance>
<outbound-resourceadapter>
<connection-definition>
<connectionfactory-interface>javax.jms.ConnectionFactory</connectionfactory-interface>
<connectiondefinition-instance>
<name>ConnectionFactory</name>
<implemented-interface>javax.jms.QueueConnectionFactory</implemented-interface>
<implemented-interface>javax.jms.TopicConnectionFactory</implemented-interface>
<connectionmanager>
<xa-transaction>
<transaction-caching/>
</xa-transaction>
<single-pool>
<max-size>10</max-size>
<blocking-timeout-milliseconds>5000</blocking-timeout-milliseconds>
<match-one/>
</single-pool>
</connectionmanager>
<global-jndi-name>ConnectionFactory</global-jndi-name>
<!--
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
-->
</connectiondefinition-instance>
</connection-definition>
</outbound-resourceadapter>
</resourceadapter>
<adminobject>
<adminobject-interface>javax.jms.Topic</adminobject-interface>
<adminobject-class>org.codehaus.activemq.message.ActiveMQTopic</adminobject-class>
<adminobject-instance>
<message-destination-name>weatherTopic</message-destination-name>
<config-property-setting
name="PhysicalName">weatherTopic</config-property-setting>
</adminobject-instance>
</adminobject>
<adminobject>
<adminobject-interface>javax.jms.Topic</adminobject-interface>
<adminobject-class>org.codehaus.activemq.message.ActiveMQTopic</adminobject-class>
<adminobject-instance>
<message-destination-name>weatherRequestsTopic</message-destination-name>
<config-property-setting
name="PhysicalName">weatherRequestsTopic</config-property-setting>
</adminobject-instance>
</adminobject>
</connector>
然後使用 Geronimo 的部署工具部署它
D:\\geronimo>java -jar bin\\deployer.jar deploy d:\\projects\\weather\\src\\resources\
geronimo-activemq.xml repository\\activemq\\rars\\activemq-ra-3.1-SNAPSHOT.rar
Username: system
Password: manager
Deployed weather/Topics
geronimo.log 檔案現在應該會參考這些新部署的主題。
2) 現在佇列在伺服器端可用了,我們想要的是透過獨立用戶端
存取它們。
通常,流程如下:
- 聯絡 J2EE 命名伺服器(port 1099,RMI)以取得 JNDI InitialContext。
- J2EE 伺服器會自動透過 JNDI 公開 ConnectionFactory 和主題
,因此 InitialContext 可讓您擷取 ConnectionFactory 和主題
。 - 一旦您擁有主題,就可以使用它們。
但是,ActiveMQ Classic 的 JNDI 實作不會與命名伺服器交談。它
是 JNDI 用戶端的精簡版本,僅允許直接從 JMS 實例取得主題和
佇列。
因此,您必須提供 JMS 伺服器位址,而不是提供命名伺服器位址。
伺服器位址。
大多數 JNDI 實作都使用 java.naming.provider.url 屬性來指定
命名伺服器的位址。ActiveMQ Classic 使用 brokerURL。使用
java.naming.provider.url 反而會導致 ActiveMQ Classic 嘗試載入
整個 Broker。
3) 因此,現在我們已經說明了流程,讓我們詳細說明 Spring 的做法
。
- 建立一個可在類別路徑中使用的 bootstrap.properties 檔案
jms.connectionFactoryName=ConnectionFactory jms.jndiProviderUrl=tcp://127.0.0.1:61616 jms.jndiContextFactory=org.activemq.jndi.ActiveMQInitialContextFactory jms.weatherTopic=weatherTopic jms.weatherRequestsTopic=weatherRequestsTopic
-
現在,在您的 Spring 描述檔中,宣告將從 bootstrap.properties 檔案讀取屬性的 bean
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"><value>classpath:/bootstrap.properties</value></property> </bean>
- 建立 JNDI 範本(Spring 專用的 JNDI InitialContext 包裝器)```
${jms.jndiContextFactory} <!-- ActiveMQ Classic 專用 --> <!-- ActiveMQ Classic Broker 的位址 -->${jms.jndiProviderUrl} <!-- 一些主題註冊,因為我們使用的是虛擬 JNDI 實作 -->${jms.weatherTopic} ${jms.weatherRequestsTopic} ```
-
從 JNDI 環境擷取 ConnectionFactory
<bean id="internalJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>${jms.connectionFactoryName}</value> </property> </bean>
我不百分之百確定,但我認為您可以放入任何工廠名稱,它都會
運作。(在 JNDI 環境實際聯絡命名伺服器的情況下,
它應該符合已部署 ConnectionFactory 的名稱) - 從 JNDI 環境取得主題實例
<bean id="weatherTopic" class="org.springframework.jndi.JndiObjectFactoryBean" singleton="true"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>${jms.weatherTopic}</value> </property> </bean> <bean id="weatherRequestTopic" class="org.springframework.jndi.JndiObjectFactoryBean" singleton="true"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>${jms.weatherRequestsTopic}</value> </property> </bean>
- 現在,您可以隨意重複使用這些主題 bean。