工作中用到了,记一下。
工程配置文件目录如下:
1.spring配置文件中加入
<!-- 加载jms相关的配置文件 -->
<import resource="./spring-mq.xml" />
2.spring-mq.xml文件如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd">
<!-- 配置JMS链接模版 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activeMq.brokerURL}" />
<property name="clientID" value="${clientId}"/>
<!-- <property name="userName" value="${ActiveMQ.userName}" />
<property name="password" value="${ActiveMQ.passWord}" />-->
<!-- 是否异步发送 -->
<property name="useAsyncSend" value="true"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- 以下为生成者配置文件 -->
<!-- 配置JMS模版 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestination" ref="destination"/>
<property name="connectionFactory" ref="connectionFactory" />
<!-- value为true为发布/订阅模式; value为false为点对点模式-->
<property name="pubSubDomain" value="false" />
<!--deliveryMode, priority, timeToLive 的开关,要生效,必须配置为true,默认false -->
<property name="explicitQosEnabled" value="true" />
<!--发送模式 DeliveryMode.NON_PERSISTENT=1:非持久 ; DeliveryMode.PERSISTENT=2:持久 -->
<property name="deliveryMode" value="1" />
<!--消息应答方式 Session.AUTO_ACKNOWLEDGE 消息自动签收 Session.CLIENT_ACKNOWLEDGE 客户端调用acknowledge方法手动签收 Session.DUPS_OK_ACKNOWLEDGE 不必必须签收,消息可能会重复发送-->
<property name="sessionAcknowledgeMode" value="2" />
</bean>
<!-- 采用TCP长连接方式, 避免每次建立短连接需要的额外工作时间 -->
<!--<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConectionFactory">
<constructor-arg ref="connectionFactory"></constructor-arg>
</bean>
-->
<!-- 发送消息的目的地(一个队列) -->
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<!--设置生成者 消息队列的名字 -->
<constructor-arg index="0" value="${carinfosyncQueue},${ceshiQueue}" />
</bean>
<!-- 以下为消费者配置文件 -->
<!--消息获取类 路径一定要对-->
<bean id="messageReceiver" class="com.blue.controller.OnMessageReceiver" />
<!--给消息获取类加个监听让他能自动获取消息 -->
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="destination" />
<property name="messageListener" ref="messageReceiver" />
<!-- 该属性值默认为false,这样JMS在进行消息监听的时候就会进行事务控制, 当在接收消息时监听器执行失败时JMS就会对接收到的消息进行回滚, -->
<property name="sessionTransacted" value="false" />
</bean>
</beans>
上边是生成者配置,下边是消费者配置。
这样一个destination就可以配置多个不用队列,也可以监听多个队列
3.生成者代码:
包:
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import net.sf.json.JSONObject;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
引入:
@Resource
private JmsTemplate jmsTemplate;
@Qualifier("destination")
private Destination destination;
方法:通过遍历可以获取配置文件中的多个队列
public void sendMessage(Destination destination, final String message,String queueName) {
ActiveMQDestination activeMQDestination=(ActiveMQDestination) destination;
ActiveMQDestination[] compositeDestinations = activeMQDestination.getCompositeDestinations();
for (int i = 0; i < compositeDestinations.length; i++) {
String name=compositeDestinations[i].getPhysicalName();
if(queueName.equals(name)){
System.out.println("生成者发送信息 队列:" +name +"参数:"+message);
jmsTemplate.send(name, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
};
}
}
4.消费方:跟消费方配置文件一定要对上
package com.blue.controller;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.apache.activemq.command.ActiveMQDestination;
import org.springframework.beans.factory.annotation.Autowired;
public class OnMessageReceiver implements MessageListener{
public void onMessage(Message m){
try {
ActiveMQDestination queues=(ActiveMQDestination)m.getJMSDestination();
TextMessage message = (TextMessage)m;
System.out.println("消费者消费carinfosyncQueue队列:文本消息"+message.getText());
// if(m instanceof TextMessage){ //接收文本消息
// TextMessage message = (TextMessage)m;
// System.out.println("消费者消费:文本消息"+message.getText());
// }else if(m instanceof MapMessage){ //接收键值对消息
// MapMessage message = (MapMessage)m;
System.out.println(message.getLong("age"));
System.out.println(message.getDouble("sarray"));
System.out.println(message.getString("username"));
// System.out.println("消费者消费:键值对消息 "+message);
// }else if(m instanceof StreamMessage){ //接收流消息
// StreamMessage message = (StreamMessage)m;
// System.out.println("消费者消费:流消息"+message.readString());
// System.out.println("消费者消费:流消息"+message.readLong());
// }else if(m instanceof BytesMessage){ //接收字节消息
// byte[] b = new byte[1024];
// int len = -1;
// BytesMessage message = (BytesMessage)m;
// while((len=message.readBytes(b))!=-1){
// System.out.println("消费者消费:字节消息"+new String(b, 0, len));
// }
// }else if(m instanceof ObjectMessage){ //接收对象消息
// ObjectMessage message = (ObjectMessage)m;
User user = (User)message.getObject();
// System.out.println("消费者消费:对象消息"+message);
// }else{
// System.out.println(m);
// }
} catch (Exception e) {
}
}
}
我的需求是:先接受队列中的消息,进行消费,然后同时也是生成者返回到队列中。因为都是json形式。所以没有对其他类型做判断。很早以前用过ActiveMQ,在电商项目中,时间久了忘记了,正好现在项目中用到。温故知新。