Spring整合RabbitMQ
导入依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
生产者端配置
<!-- 创建RabbitMQ连接工厂-->
<rabbit:connection-factory id="factory" host="192.168.31.14" port="5672"
username="hello"
password="123456"
virtual-host="/myhost"></rabbit:connection-factory>
<!--声明交换机 auto-declare:true 表示创建交换机 -->
<rabbit:topic-exchange name="order_exchange" auto-declare="true" auto-delete="false" durable="true" >
</rabbit:topic-exchange>
<!--声明队列durable="true" 创建队列,有则使用,无则创建-->
<rabbit:queue name="order_queue" auto-delete="false" durable="true" auto-declare="true" exclusive="false">
</rabbit:queue>
<!--将队列与交换机绑定-->
<rabbit:topic-exchange name="order_exchange">
<rabbit:bindings>
<rabbit:binding pattern="hello1.#" queue="order_queue"></rabbit:binding>
</rabbit:bindings>
</rabbit:topic-exchange>
<!--RabbitTemplate对象是spring对操作RatbbitMQ的代码封装,简化代码的开发工作 exchange:定义要投递消息的交换机 (可选的) -->
<rabbit:template id="template" connection-factory="factory"
exchange="order_exchange" mandatory="true" confirm-callback="confirmListener"
return-callback="returnListener">
</rabbit:template>
<!-- 监听-->
<bean class="com.woniu.config.OderReturnListener" id="returnListener"></bean>
<!--由交换机分发信息给匹配key的队列后剩下的信息的监听-->
<bean class="com.woniu.config.OrderConfirmListener" id="confirmListener"></bean>
<!--将传递的信息转为json字符串-->
<bean class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" name="jsonMessageConverter"></bean>
<!--扫描指定的包,将里面的打了特定注解的类纳入Spring容器中-->
<context:component-scan base-package="com.*.*"></context:component-scan>
<!--用来管理,创建队列和交换机,如事先已创建好交换机和队列则此项可以不加-->
<rabbit:admin connection-factory="factory"></rabbit:admin>
//对消息是否发送到交换机进行监听
public class OrderConfirmListener implements RabbitTemplate.ConfirmCallback {
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
System.out.println("消息的tag:" + correlationData.getId());
System.out.println("接收到的消息" + s);
}
}
//对消息是否从交换机发送到队列进行监听
public class OderReturnListener implements RabbitTemplate.ReturnCallback {
@Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println("返回的错误编码:"+i);
System.out.println("返回的错误消息:"+s);
System.out.println("交换机:"+s1);
System.out.println("路由key");
System.out.println("返回的消息:"+new String(message.getBody()));
}
}
通过配置文件指定监听返回处理类和方法,有人和我说是可以的,但是我没测试出来,貌似是版本问题,而且从理论上讲没理由不行的,如果有大佬发现我哪里配错了并且不嫌麻烦告诉我的话,万分感激,另外可以通过配置类的方式来实现监听,我在下一篇springboot的配置中再来说明。
消费者端配置
<rabbit:connection-factory id="factory" host="192.168.31.14" virtual-host="/myhost" username="hello"
password="123456" port="5672"></rabbit:connection-factory>
<!--监听一旦order_queue队列有消息,则调用orderConsumer对象的recv()方法来进行处理消息
acknowledge="manual" 手动签收
channel.basicComsume("队列",false,回调) -->
<rabbit:listener-container connection-factory="factory" acknowledge="manual">
<rabbit:listener ref="orderConsumer" method="recv" queue-names="order_queue"></rabbit:listener>
</rabbit:listener-container>
<!--注入模板-->
<rabbit:template id="template" connection-factory="factory"
exchange="order_exchange" mandatory-expression="#{true}" >
</rabbit:template>
注:因为在生产者端已经声明了交换机和队列,这里就不需要再声明了,当然如果消息队列中并没有预先创建交换机和队列,这里又先运行消费者端则会报错,原因是消费者端找不到队列,所以为了保险,消费者端也可以声明交换机和队列
测试代码
@ContextConfiguration(value = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class AppTest {
@Autowired
private OrderProducer producer;
@Test
public void shouldAnswerWithTrue() {
Orders orders = new Orders();
orders.setCreateTime(new Date());
orders.setOrderNo(10001);
producer.sendOrder("hello."+orders.getCreateTime(),orders);
}
}
接收消息代码
public void recv(Orders orders){
System.out.println("接收到的数据:"+orders.getCreateTime());
System.out.println("接收到的数据:"+orders.getOrderNo());
}