准备工作:需要有一个RabbitMQ服务,如果是本地电脑,自行上官网下载并安装RabbitMQ软件,在rabbitmq安装之前,童鞋们需要安装erlang,因为rabbitmq是用erlang写的。
1. maven配置
除了spring常用的基础包外,我们还需要下面这个包
<!--rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
2. 创建几个生产者和消费者类
jar包加上去下载好之后我们可以进行下一步,创建几个类
- 消息生产者类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
/**
* 消息生产者
*/
@Service
public class TestRabbitMQProducer {
private Logger logger = LoggerFactory.getLogger(TestRabbitMQProducer.class);
@Resource(name="amqpTemplate")
private AmqpTemplate amqpTemplate;
public void sendMessage(Object message) throws IOException {
logger.info("to send message:{}", message);
//下面这句是发送一条数据到对应队列,key是配置文件中exchange中配置的对应key
amqpTemplate.convertAndSend("LeaveQueueKey", message);
amqpTemplate.convertAndSend("UserinfoQueueKey", message);
}
}
- 消费者一
消费者一:处理用户信息
package cn.leave.task;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import cn.leave.weixinentity.UserInfo;
/**
* 消息消费者一
*/
public class UserInfoMessageConsumer implements MessageListener {
private Logger logger = LoggerFactory.getLogger(UserInfoMessageConsumer.class);
/**
* 实现MessageListener的消息接收接口
*/
@Override
public void onMessage(Message message, Channel channel) {
logger.info("消费者接受消息 message------->:{}", message);
try {
//消息转换为对象
UserInfo userInfo=(UserInfo) getObjectFromBytes(message.getBody());
//TODO 使用对象,加入业务逻辑
......
//完成任务 反馈给RabbitMQ,从队列删除
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* //字节码转化为对象(反序列化)
* @param objBytes
* @return
* @throws Exception
*/
public Object getObjectFromBytes(byte[] objBytes) throws Exception {
if (objBytes == null || objBytes.length == 0) {
return null;
}
ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
}
- 消费者二
消费者二:处理假单信息
package cn.leave.task;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import cn.leave.entity.Leave;
/**
* 消息消费者一
*/
public class LeaveMessageConsumer implements MessageListener {
private Logger logger = LoggerFactory.getLogger(LeaveMessageConsumer.class);
/**
* 实现MessageListener的消息接收接口
*/
@Override
public void onMessage(Message message, Channel channel) {
logger.info("消费者接受消息 message------->:{}", message);
try {
//消息转换为对象
Leave leave=(Leave) getObjectFromBytes(message.getBody());
//TODO 使用对象,此处加入业务逻辑....
......
//完成任务 反馈给RabbitMQ,从队列删除
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* //字节码转化为对象(反序列化)
* @param objBytes
* @return
* @throws Exception
*/
public Object getObjectFromBytes(byte[] objBytes) throws Exception {
if (objBytes == null || objBytes.length == 0) {
return null;
}
ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
}
3.创建配置文件
下面就是spring中配置RabbitMQ,我这单独写在了一个配置文件中
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.3.xsd">
<!--1、创建工厂连接 -->
<rabbit:connection-factory id="rabbitConnectionFactory"
username="guest" password="guest" host="127.0.0.1" port="5672" />
<!--定义rabbit template用于数据的接收和发送 -->
<rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" exchange="exchangeConfirmLeave" />
<!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
<rabbit:admin connection-factory="rabbitConnectionFactory" />
<!--定义queue 这里的name会在RabbitMQ服务那边创建对应名字的队列 -->
<rabbit:queue name="LeaveQueue" durable="true" auto-delete="false" exclusive="false" />
<rabbit:queue name="UserinfoQueue" durable="true" auto-delete="false" exclusive="false" />
<!-- 定义direct exchange,绑定queueTest -->
<rabbit:direct-exchange name="exchangeConfirmLeave" durable="true" auto-delete="false">
<rabbit:bindings>
<!--这里可以放多个dinding-->
<!-- queue 是上面"定义queue" key是发送消息时使用的key-->
<rabbit:binding queue="LeaveQueue" key="LeaveQueueKey">
</rabbit:binding>
<rabbit:binding queue="UserinfoQueue" key="UserinfoQueueKey">
</rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- 加载消息接收者 前面声明的监听器类-->
<bean id="leaveMessageConsumer" class="cn.leave.task.LeaveMessageConsumer"></bean>
<bean id="userInfoMessageConsumer" class="cn.leave.task.UserInfoMessageConsumer"></bean>
<!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
<!-- acknowledge="manual" 为了保证数据不被丢失,RabbitMQ支持消息确认机制,即ack。为了保证数据能被正确处理而不仅仅是被Consumer收到, -->
<rabbit:listener-container
connection-factory="rabbitConnectionFactory" acknowledge="manual"
prefetch="10">
<!--定义监听器 这里可以放多个监听器
queues:监听的队列 多个可以","隔开;ref:监听器在spring中的引用 -->
<rabbit:listener queues="LeaveQueue" ref="leaveMessageConsumer" />
<rabbit:listener queues="UserinfoQueue" ref="userInfoMessageConsumer" />
</rabbit:listener-container>
</beans>
下面一段一段解释一下
- connect-factory 管理 rabbitmq服务 的连接,这个参数不再解释
<!--1、创建工厂连接 -->
<rabbit:connection-factory id="rabbitConnectionFactory"
username="guest" password="guest" host="127.0.0.1" port="5672" />
- rabbit:template 类似于mysql中的template ,对队列进行一些操作,如加入消息到队列
connection-factory:使用的连接工厂
exchange:使用的交换机
<!--定义rabbit template用于数据的接收和发送 -->
<rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" exchange="exchangeConfirmLeave" />
- exchange 交换机,用来控制消息发送到哪个队列
direct-exchange:直连交换机,全名匹配
durable:是否持久化
auto_delete: 当所有消费客户端连接断开后,是否自动删除队列
rabbit:binding:设置消息queue匹配的key,绑定其关系
<!-- 定义direct exchange,绑定queueTest -->
<rabbit:direct-exchange name="exchangeConfirmLeave" durable="true" auto-delete="false">
<rabbit:bindings>
<!--这里可以放多个dinding-->
<!-- queue 是上面"定义queue" key是发送消息时使用的key-->
<rabbit:binding queue="LeaveQueue" key="LeaveQueueKey"> </rabbit:binding>
<rabbit:binding queue="UserinfoQueue" key="UserinfoQueueKey"> </rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange>
- rabbit:queue 定义队列
durable:是否持久化
exclusive: 仅创建者可以使用的私有队列,断开后自动删除
auto_delete: 当所有消费客户端连接断开后,是否自动删除队列
<!--定义queue 这里的name会在RabbitMQ服务那边创建对应名字的队列 -->
<rabbit:queue name="LeaveQueue" durable="true" auto-delete="false" exclusive="false" />
<rabbit:queue name="UserinfoQueue" durable="true" auto-delete="false" exclusive="false" />
- rabbit:admin通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成
<!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
<rabbit:admin connection-factory="rabbitConnectionFactory" />
- 配置监听器
<!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
<!-- acknowledge="manual" 为了保证数据不被丢失,RabbitMQ支持消息确认机制,即ack。为了保证数据能被正确处理而不仅仅是被Consumer收到, -->
<rabbit:listener-container
connection-factory="rabbitConnectionFactory" acknowledge="manual"
prefetch="10">
<!--定义监听器 这里可以放多个监听器
queues:监听的队列 多个可以","隔开;ref:监听器在spring中的引用 -->
<rabbit:listener queues="LeaveQueue" ref="leaveMessageConsumer" />
<rabbit:listener queues="UserinfoQueue" ref="userInfoMessageConsumer" />
</rabbit:listener-container>
剩下的spring基础配置就不放到这了,下面是一些名词的解释
connect-factory进行连接rabbitmq服务.
template用于连接factory并指定exchange, 这上面还能直接指定rout-key.
admin相当于一个管理员的角色…可以将exchange和queue进行管理,
queue和topic-exchange分别定义队列和路由器, 这里需要用declared-by指定管理员,从而连接到相应的factory.
listener-container用于消费者的监听,rabbit配置中是可以指定某个类的某个方法的,如下
<rabbit:listener-container message-converter="jackson2JsonMessageConverter">
<rabbit:listener queue-names="RESPONSE_QUEUE1, RESPONSE_QUEUE2, RESPONSE_QUEUE3, RESPONSE_QUEUE4, RESPONSE_QUEUE5"
ref="responseMapConsumer" method="listenResponseMap"/>
</rabbit:listener-container>
到此配置完成,启动项目,执行一下生产者的sendMessage()方法就可以把消息发送给RabbitMQ,然后监听器监听到消息就可以执行onMessage方法接受消息了
扫描二维码关注公众号,回复:
10558004 查看本文章