JBoss自己支持JMS(經過JNDI公佈),只須要在deploy/jms裏配置相應xml文件,把Topic/Queue/ConnectionFactory配好便可,默認Jboss啓動會在1099端口監聽JMS消息。對應Spring配置是針對消息處理器設置以下:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>ConnectionFactory_JNDI_NAME</value>
</property>
</bean>
<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>TOPIC_JNDI_NAME</value>
</property>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="connectionFactory"/>
</property>
<property name="defaultDestination">
<ref bean="destination"/>
</property>
<property name="receiveTimeout">
<value>3000</value>
</property>
</bean>
<bean id="messageListener"
class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="com.companya.projectb.*.ImplClass ">
<!—Implement the interface of handleMessage(Object message) -->
</bean>
</constructor-arg>
</bean>
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="destination" />
<property name="subscriptionDurable" value="false" />
<property name="messageListener" ref="messageListener" />
<property name="exposeListenerSession" value="false" />
</bean>
</beans>
Tomcat自己沒有對JMS的支持,全部須要用第三方組件來實現,如今OSS比較流行的是ActiveMQ和JMSOpen,ActiveMQ是Apache基金開源項目,支持力度/更新都不錯,因此選用ActiveMQ(http://activemq.apache.org )。
ActiveMQ能夠做爲standalone application運行於JVM,也能夠做爲web application運行於J2EE容器如Tomcat, Jboss, Jetty等上。這些都是能夠從官方網站看幫助文檔很簡單地下載安裝部署。下面的xml配置能夠實現Broker在web application內部嵌入式(embedded broker)運行:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- lets create an embedded ActiveMQ Broker -->
<amq:broker useJmx="false" persistent="false">
<amq:transportConnectors>
<amq:transportConnector uri="${ broker.url}" />
</amq:transportConnectors>
</amq:broker>
<!-- ActiveMQ destinations to use physicalName is the name to connect topic/queue -->
<amq:topic id="destination" physicalName="${ topic.name}"/>
<!-- JMS ConnectionFactory to use, configuring the embedded broker using XML -->
<amq:connectionFactory id="jmsFactory" brokerURL="${broker.url}"/>
<!-- Spring JMS Template -->
<bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
…
</beans>
在個人部署過程當中,發現ActiveMQ必須是5.x版本以上才支持broker配置標籤。而activemq 5.x網上的binary版本是jdk6編譯的,因此兼容性必須考慮好。ActiveMQ的依賴jar文件包括geronimo-jms_1.1_spec-1.1.1.jar, geronimo-j2ee-management_1.1_spec-1.0.1.jar, geronimo-jta_1.0.1B_spec-1.0.1.jar, activemq-core-5.5.1.jar, activemq-web-5.5.1.jar, slf4j-simple-1.6.4.jar, slf4j-api-1.6.4.jar。特別要注意slf4j的版本必須保持兼容。網絡上下載的示例裏有slf4j-api-1.5.11.jar的,這個跟slf4j-simple-1.6.4.jar版本不兼容。在xml配置中也能夠用JNDI方式配置,不過這樣須要在context.xml文件裏配置Resource。
另外網絡上不少文檔說url配置成tcp://localhost:61616,其實這樣的配置只支持本機的消息傳遞,若是遠程主機要連上本地activeMQ,會出現connection refused錯誤,只須要把localhost改爲0.0.0.0便可實現遠程鏈接了。61616是activeMQ默認端口,能夠配成別的端口。tcp是傳輸協議,能夠支持http, vm等。ActiveMQ還支持failover, multicast,persistence等增強功能。
客戶端java代碼示例以下(其中的url參數爲tcp://hostname:port, topicname是physicalName):
org.apache.activemq.ActiveMQConnectionFactory factory =
new org.apache.activemq.ActiveMQConnectionFactory();
factory.setBrokerURL(brokerUrl);
connActiveMQ = factory.createConnection();
connActiveMQ.start();
sessActiveMQ = connActiveMQ.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = sessActiveMQ.createTopic(topicname);
MessageProducer producer =sessActiveMQ.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
MapMessage message = sessActiveMQ.createMapMessage(); //TextMessage, etc.
message.setObject(key, value);
producer.send(message);
sessActiveMQ.close();
connActiveMQ.stop();