ActiveMQ——7.Spring-jms的配置
来源:互联网 发布:君何以知燕王句式 编辑:程序博客网 时间:2024/06/07 01:13
概述
如何使用spring-jms来简化jms客户端的开发?
这篇文章主要记录如何配置以便以后复用。
producer端
producer端负责发送,这里使用JmsTemplate。
spring配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" 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-4.2.xsd"> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <!-- create template for send message --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- bind the connection factory --> <property name="connectionFactory" ref="connectionFactory" /> <property name="defaultDestinationName" value="jms-config" /> </bean></beans>
JmsTemplate默认将jms-config解析为Queue类型的Destination。如果需要将其解析为Topic类型,需要为jmsTemplate指定属性pubSubDomain=true,配置如下:
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- bind the connection factory --> <property name="connectionFactory" ref="connectionFactory" /> <property name="pubSubDomain" value="true" /> <property name="defaultDestinationName" value="jms-config" /></bean>
测试类
package cn.sinobest.asj.producer.springsupport.jt;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.jms.core.JmsTemplate;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class) // 配置spring组件运行时@ContextConfiguration(locations="classpath:spring-jms-demo.xml") // 配置文件public class JmsTemplateSendWithContextTest { @Resource(name = "jmsTemplate") private JmsTemplate jt; @Test public void testSendToDefaultDestination() { String message = "you can config JmsTemplate in xml, then use it for send."; jt.convertAndSend(message); }}展示这个测试类,是想告诉大家使用Spring+JUnit4的注解编写单元测试,可以非常方便的加载Spring配置并初始化bean资源;使用Resource注解可以获取bean资源。
consumer端
consumer端负责接收,接收有同步、异步两种方式。
同步接收
这里使用JmsTemplate进行同步接收。上面已经给过了使用JmsTemplate发送的配置,接收和发送的配置能有什么区别呢?
如果我们不希望客户端一直阻塞等待消息,那么需要关心receiveTimeout属性,单位毫秒。如果超过了这个时间,还没有接收到消息,就返回null。
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- bind the connection factory --> <property name="connectionFactory" ref="connectionFactory" /> <property name="defaultDestinationName" value="jms-config" /> <property name="receiveTimeout" value="3000" /></bean>
异步接收
异步接收是基于监听器的接收,传统的配置方式是配置一个ListenerContainer的bean,在这个bean里维护listener。还有一种精简的配置方案,可以在一个container中放置多个listener。
传统的配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" 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-4.2.xsd"> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="messageListener" class="cn.sinobest.asj.consumer.springsupport.async.SimpleMessageListener" /> <bean id="messageContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="destinationName" value="jms-config" /> <property name="messageListener" ref="messageListener" /> </bean></beans>
其中,SimpleMessageListener是接口javax.jms.MessageListener的实现类。
DefaultMessageListenerContainer负责将messageListener注册到connectionFactory的destination,一旦destination中有消息,就会将消息推送给messageListener。
DefaultMessageListenerContainer有很多特性的配置,下面择要介绍:
1.Destination及类型
使用下面的API,可以设置Destination
- public void setPubSubDomain(boolean pubSubDomain)
设置destination的类型,true-Topics,false-Queues;默认为false。 - public void setDestinationName(String destinationName)
设置destination的name,结合pubSubDomain使用,根据destinationName解析为具体的Destination。 - public void setDestination(Destination destination)
设置destination。
2.多线程
一个DMLC的实例,只能管理一个MessageListener实例,但是可以使用下面的方法设置多线程:
- public void setConcurrency(String concurrency)
通过"lower-upper"格式的字符串,设置线程数的下限和上限,如"5-10";或者仅设置上限,下限默认为1,如"10"。
如果没有使用事务,多线程可以显著提高监听器的接收速度。
3.确认模式
下面的API用来设置确认模式:
- public void setSessionAcknowledgeMode(int sessionAcknowledgeMode)
设置确认模式,sessionAcknowledgeMode可以取javax.jms.Session.AUTO_ACKNOWLEDGE(默认),javax.jms.Session.CLIENT_ACKNOWLEDGE,javax.jms.Session.DUPS_OK_ACKNOWLEDGE。 - public void setSessionAcknowledgeModeName(String constantName)
通过名字来设置确认模式,默认为"AUTO_ACKNOWLEDGE"。
4.事务
下面的API,用来设置事务:
- public void setSessionTransacted(boolean sessionTransacted)设置是否使用事务,默认为false。
更多DefaultMessageListenerContainer的相关配置,参考其API。
精简的配置
称之为精简版的配置,因为一个容器可以配置多个监听器。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.1.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.12.1.xsd"> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <!-- 定义Topic监听器 --> <jms:listener-container destination-type="topic" container-type="default" connection-factory="connectionFactory" acknowledge="auto"> <!-- 这里的Destination是自定义的,ref对应的是创建的messagelistener类名小写 --> <jms:listener destination="test.topic" ref="topicReceiver1"/> <jms:listener destination="test.topic" ref="topicReceiver2"/> </jms:listener-container> </beans>注意:精简版的schema和传统版不一样,详细的精简版可以参考Spring整个ActiveMQ(精简版配置)
listener-container作为容器,可以有多个listener子元素,每个listener代表一个监听器。
1.Destination类型
listener-container有destination-type属性,可以取值["queue", "topic"],默认为"queue",它决定了listener将destination解析为Queue还是Topic类型。
2.pojo监听器
listener会对消息进行转换,所以ref的目标bean是一个pojo,method是这个pojo的方法的名字——这个方法的参数要和Message中的数据类型兼容。下面给出我们使用的topicReceiver1:
package com.gwd.mq.producer.topic; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import org.springframework.stereotype.Component; @Component public class TopicReceiver1 implements MessageListener{ public void onMessage(Message message) { try { System.out.println("TopicReceiver1接收到消息:"+((TextMessage)message).getText()); } catch (JMSException e) { e.printStackTrace(); } } }
3.多线程
为listener-container元素设置concurrency属性,可以指定线程数的下限和上限。这一点和DefaultMessageListenerContainer的相同。
4.确认模式和事务4
listener-container的acknowledge属性,可以指定确认模式或者事务,取值范围["auto", "client", "dups-ok", "transacted"];默认为"auto",事务使用"transacted"。
更多精简配置相关的参数,参考spring-jms-4.2.xsd
可信任的包
ObjectMessage的使用机制是不安全的,ActiveMQ自5.12.2和5.13.0之后,强制consumer端声明一份可信任的包列表,只有当ObjectMessage中的Object在可信任包内,才能被提取出来。
添加可信任的一般常用两种,一种按自己的需求添加,另一种是添加全部可信任//按需添加信任代码版设置ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");factory.setTrustedPackages(new ArrayList(Arrays.asList("org.apache.activemq.test,org.apache.camel.test".split(","))));
//完全信任的代码版设置ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");factory.setTrustAllPackages(true);
配置版分别对应如下:
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> <property name="trustedPackages"> <list> <value>org.apache.activemq.test</value> <value>org.apache.camel.test</value> </list> </property></bean><bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="connectionFactory"/></bean><bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfig"/></bean>
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> <property name="trustAllPackages" value="true"/></bean><bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="connectionFactory"/></bean><bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfig"/></bean>关于ObjectMessage安全性的说明,参考官方文档
ConnectionFactory的bean配置
一般有如下几种:
1.ActiveMQConnectionFactory
在前面的配置中,我们已经接触了这个配置:
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"><property name="brokerURL" value="tcp://localhost:61616" /></bean>
2.SingleConnectionFactory
使用org.springframework.jms.connection.SingleConnectionFactory对ActiveMQConnectionFactory进行包装,建议用于测试或者单机的环境。
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory"> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> </property></bean>
3.PooledConnectionFactory
使用org.apache.activemq.pool.PooledConnectionFactory对ActiveMQConnectionFactory进行包装。
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory"> <bean class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> </property></bean>
方式的选择:
1.如果只需要一个connection选择ActiveMQConnectionFactory,如果需要多个connection选择PooledConnectionFactory
2.By default the pooled version will Idle out old connections after some time of non-use. The ActiveMQ connection created from its factory is valid until you call close() or it is no longer referenced。(摘自stackoverflow,大致意思是PooledConnectionFactory会释放长连接,ActiveMQConnectionFactory不会释放直到你关闭它或者不再引用)
3.SingleConnectionFactory一般用于测试或者单机环境
阅读全文
0 0
- ActiveMQ——7.Spring-jms的配置
- jms+spring+activemq配置
- JMS——Spring+ActiveMQ
- Spring+ActiveMQ+Mysql 配置JMS
- Spring+ActiveMQ+Mysql 配置JMS
- JMS--Spring整合JMS(一)——基于ActiveMQ实现
- ActiveMQ深入浅出JMS(四)——Spring和ActiveMQ整合的完整实例
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring Boot揭秘与实战
- f i n a l 的注意事项
- HashMap和Hashtable的区别
- MySQL主主数据同步
- 区块链和以太坊用于 JavaScript 和 React 开发
- ActiveMQ——7.Spring-jms的配置
- QTcpSocket和QTcpServer实现聊天小工具
- ArrayList、LinkedList、Vector的区别
- JAVA代码根据IP/掩码位数格式地址段得到起始地址和结束地址,可用IP数量,掩码
- 设计模式六大原则(3):依赖倒置原则
- 文章标题
- android 修改源码framework后如何编译
- STL的string判断为空字符串
- Docker部署(四):Gogs