RabbitMq的介绍和基本的认识在上一篇中讲过,不再赘述。直接上代码,整合springboot RabbitMq
Maven中引入RabbitMq依赖
repository.org.springframework.amqp
spring-rabbit
2.0.3.RELEASE
第一种:
首先先定义一个队列
package com.example.rabbit.demo.conf;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Title: RabbitMqConfig
* Description:
* Company: [email protected]
* @author pengchengDu
* @date 2018年8月22日
*/
@Configuration
public class RabbitMqConfig {
@Bean
public Queue queue() {
//定义队列
return new Queue("queueTest1");
}
}
其次定义发送者,编写发送的接口
@Autowired
private AmqpTemplate amqpTemplate;
//一个生产者丢信息到一个队列对应一个消费者
@RequestMapping(value = "/send", method = RequestMethod.GET)
public String send() {
String content = "Date:" + new Date();
amqpTemplate.convertAndSend("queueTest", content);
return content;
}
最后定义消费者(接收的接口)
package com.example.rabbit.demo.queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* Title: Receiver1
* Description:
* Company: [email protected]
* @author pengchengDu
* @date 2018年8月22日
*/
@Component
@RabbitListener(queues = "queueTest1")
public class Receiver1 {
@RabbitHandler
public void receiver(String msg){
System.out.println("Test1 receiver1:"+msg);
}
}
第二种:
消息队列和发送者的不变,多增加一个消息的消费者Receiver2
package com.example.rabbit.demo.queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* Title: Receiver1
* Description:
* Company: [email protected]
* @author pengchengDu
* @date 2018年8月22日
*/
@Component
@RabbitListener(queues = "queueTest2")
public class Receiver2 {
@RabbitHandler
public void receiver(String msg){
System.out.println("Test1 receiver2:"+msg);
}
}
//一个生产者丢信息到一个队列对应多个消费者
@RequestMapping(value = "/multisend",method = RequestMethod.GET)
public String multisend(){
StringBuffer time = new StringBuffer();
for (int i =0;i<10;i++) {
long nanoTime = System.nanoTime();
amqpTemplate.convertAndSend("queueTest", "第"+i+"次发送"+nanoTime);
time.append(""+ nanoTime+"
");
}
return time.toString();
}
第三种:定义多个消息队列,与第二种的区别是有两个消息队列,消费者相同。
@Configuration
public class RabbitMqConfig {
@Bean
public Queue queue1() {
//定义队列
return new Queue("queueTest1");
}
@Bean
public Queue queue2() {
//定义队列
return new Queue("queueTest2");
}
}
//一个生产者直接丢信息到多个队列对多个消费者
@RequestMapping(value = "/multisend2more",method = RequestMethod.GET)
public String multisend2more(){
StringBuffer time = new StringBuffer();
for (int i =0;i<10;i++) {
long nanoTime = System.nanoTime();
amqpTemplate.convertAndSend("queueTest1", "第"+i+"次发送"+nanoTime);
amqpTemplate.convertAndSend("queueTest2", "第"+i+"次发送"+nanoTime);
time.append(""+ nanoTime+"
");
}
return time.toString();
}
第四种:定义交换机Exchange 和 Topic
package com.example.rabbit.demo.conf;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TopicConfig {
//只接受一个message
public final static String message = "topic.message";
//接收多个messages
public final static String messages = "topic.messages";
@Bean
public Queue queueMessage() {
return new Queue(TopicConfig.message);
}
@Bean
public Queue queueMessages() {
return new Queue(TopicConfig.messages);
}
@Bean
TopicExchange exchange() {
return new TopicExchange("exchange");
}
@Bean
Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
}
@Bean
Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
//这里的#表示零个或多个词。
return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
}
}
定义不同的发送者:
@RequestMapping(value = "topic1send",method = RequestMethod.GET)
public String topic1send(){
String content = "我是topic1";
System.out.println("发送者说"+content);
this.amqpTemplate.convertAndSend("exchange", "topic.message", content);
return content;
}
@RequestMapping(value = "topic2send",method = RequestMethod.GET)
public String topic2send() {
String content = "我是topic2";
System.out.println("发送者说"+content);
this.amqpTemplate.convertAndSend("exchange", "topic.messages", content);
return content;
}
定义不同的消费者
@Component
@RabbitListener(queues = "topic.messages")
public class TopicReceiver2 {
@RabbitHandler
public void process(String msg){
System.out.println("Topic receiver2:"+msg);
}
}
@Component
@RabbitListener(queues = "topic.message")
public class TopicReceiver1 {
@RabbitHandler
public void process(String msg){
System.out.println("Topic receiver1:"+msg);
}
}
在rabbitMq中,Exchange的类型有四种
1、fanout 消息统统发送到订阅者中
2、direct 消息的路由取决于binging key 和routing key,会到完全匹配的queue中
3、topic
前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,它约定:
4、header: headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。