开发环境
- spring版本 5.1.3.RELEASE
- jdk 1.8
- tomcat 9
- rabbitmq 1.4.6
配置文件
<!-- rabbitMQ依赖 -->
<!-- spring相关的其他依赖请参考源码,此处不做过多描述 -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- Alibaba Fastjson框架 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.39</version>
</dependency>
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<?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:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.2.xsd">
<!--配置connection-factory,指定连接rabbit server参数 -->
<rabbit:connection-factory id="connectionFactory"
virtual-host="${mq.vhost}" username="${mq.user}" password="${mq.pwd}"
host="${mq.address}" port="${mq.port}" />
<rabbit:admin id="connectAdmin" connection-factory="connectionFactory" />
<!-- queue 队列声明 需要发送消息到哪些队列 消息系统监听队列 -->
<rabbit:queue id="taskBridge-queue" durable="true" auto-delete="false" exclusive="false" name="taskBridge-queue" />
<rabbit:queue id="taskEmwx-queue" durable="true" auto-delete="false" exclusive="false" name="taskEmwx-queue" />
<!-- topic 模式:发送端不是按固定的routing key发送消息,而是按字符串“匹配”发送,接收端同样如此 -->
<!-- 定义交换机绑定队列(路由模式) -->
<rabbit:direct-exchange name="IExchange"
id="IExchange">
<rabbit:bindings>
<rabbit:binding queue="taskBridge-queue" key="task.saveTaskList" />
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- 消息对象json转换类 -->
<bean id="jsonMessageConverter"
class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />
<!-- 定义模版 -->
<rabbit:template id="rabbitTemplate"
connection-factory="connectionFactory" exchange="IExchange"
message-converter="jsonMessageConverter" />
<!-- 消费者监听类 -->
<!-- 定义消费者 -->
<bean name="MqListenerServer" class="wh.spring.mq.service.run.MqListenerServer" />
<!-- 定义消费者监听队列 acknowledge="manual"手动ack -->
<rabbit:listener-container
connection-factory="connectionFactory" acknowledge="manual">
<rabbit:listener ref="MqListenerServer" queues="taskEmwx-queue" />
</rabbit:listener-container>
</beans>
mq.address=xxx
mq.exchange=task-exchange
mq.routingKey=task.saveTaskList
mq.queue=task-queue
mq.port=5672
mq.user=xxx
mq.pwd=xxx
mq.timeout=5000
mq.vhost=/
生产者
package wh.spring.mq.service.run;
import javax.annotation.Resource;
import org.json.JSONObject;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.rabbitmq.client.Channel;
import wh.spring.frame.base.ModelDefine;
import wh.spring.mq.base.BaseMqService;
/**
* Mq发送实现类
* @author maple
*
*/
@Service
public class MqSend implements BaseMqService{
@Resource
private RabbitTemplate rabbitTemplate;
@Override
public boolean send(String exchange, String key, JSONObject object) {
try {
if(exchange==null||"".equals(exchange))exchange = "task-exchange";
String cd_id = ModelDefine.genConfigId("mq");
rabbitTemplate.convertAndSend(exchange, key, object.toString(), new CorrelationData(cd_id));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}
消费者
package wh.spring.mq.service.run;
import org.json.JSONObject;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import com.rabbitmq.client.Channel;
import wh.spring.mq.interfaces.FlowService;
import wh.spring.mq.interfaces.MqCommand;
import wh.spring.mq.interfaces.TaskService;
/**
* mq监听 方法
* @author Administrator
*
*/
public class MqListenerServer implements ChannelAwareMessageListener{//手动ack实现监听接口 不需手动ack 可实现MessageListener
@Override
public void onMessage(Message message, Channel channel) throws Exception {
/**
* 接收 不知道为啥 发送的json字符串 有时候有转义符
*/
String string = new String(message.getBody());
// string = string.replaceAll("\\\\", "");
// string = string.substring(1, string.length()-1);
JSONObject jsonObject = new JSONObject(string);
String key = message.getMessageProperties().getReceivedRoutingKey();
Object mqCommand = null;
switch (key) {
case "task.getTaskDetail":
mqCommand = taskHandlel;
break;
case "flow.getFlowInfo":
mqCommand = flowHandle;
break;
default:
System.out.println(key);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
boolean sRet = false;
if(mqCommand!=null)
sRet = ((MqCommand) mqCommand).handleing(jsonObject);
if(sRet)
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
@Autowired
TaskService taskHandlel;
@Autowired
FlowService flowHandle;
}
总结
有好多的坑
注意
- springmvc 版本冲突 rabbitmq 只能用 1.4.6 再高的就不支持
- 路由的三种模式写法 具体模式差别没注意 topic 简单 错误少