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();
本文转自 dannyy1026 51CTO博客,原文链接:http://blog.51cto.com/dannyyuan/756008