先在pom文件中引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
再在application.properties添加配置信息
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
Direct模式
- 该模式是通过发送消息的routing key进行完全匹配的。这里的routing key匹配的是Queue的队列名称,只有当两者完全一致时才会将消息转发到该Queue中。与JMS中queue队列的模式很相似。
创建配置类SendConf.java
package com.springboot_springdatajpa.springdatajpa.interceptor;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:32
*/
@Configuration
public class SenderConf {
@Bean
public Queue queue(){
return new Queue("one");
}
@Bean
public Queue queue2(){
return new Queue("two");
}
}
创建生产者类RabbitMQProvider.java
package com.springboot_springdatajpa.springdatajpa.service;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:34
*/
@Service
public class RabbitMQProvider {
@Autowired
private AmqpTemplate amqpTemplate;
public boolean send(){
amqpTemplate.convertAndSend("one","direct test......");
return true;
}
}
创建消费者RabbitMQConsumer.java
package com.springboot_springdatajpa.springdatajpa.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:36
*/
@Service
public class RabbitMQConsumer {
@RabbitListener(queues = "one")
public void recevier(String message){
System.out.println("one收到的message是:"+message);
}
@RabbitListener(queues = "two")
public void recevier2(String message){
System.out.println("two收到的message是:"+message);
}
}
创建测试类TestController.java
package com.springboot_springdatajpa.springdatajpa.controller;
import com.springboot_springdatajpa.springdatajpa.service.RabbitMQProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:39
*/
@RestController
public class TestController {
@Autowired
private RabbitMQProvider rabbitMQProvider;
@RequestMapping("/test")
public boolean sendOne(){
return rabbitMQProvider.send();
}
}
启动该项目,浏览器访问http://localhost:8080/test
控制台输出结果
Fanout模式
该模式只要是绑定了Exchange的Queue,都会收到发送至该Exchange的消息
配置类修改为
package com.springboot_springdatajpa.springdatajpa.interceptor;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:32
*/
@Configuration
public class SenderConf {
@Bean
public Queue queue(){
return new Queue("one");
}
@Bean
public Queue queue2(){
return new Queue("two");
}
@Bean
FanoutExchange exchange(){
return new FanoutExchange("fanout");
}
@Bean
Binding bindingExchangeMessage(Queue queue,FanoutExchange fanoutExchange){
return BindingBuilder.bind(queue).to(fanoutExchange);
}
@Bean
Binding bindingExchangeMessage2(Queue queue2,FanoutExchange exchange){
return BindingBuilder.bind(queue2).to(exchange);
}
}
消息生产者类RabbitMQProvider.java
package com.springboot_springdatajpa.springdatajpa.service;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:34
*/
@Service
public class RabbitMQProvider {
@Autowired
private AmqpTemplate amqpTemplate;
public boolean send(){
amqpTemplate.convertAndSend("one","direct test......");
return true;
}
public boolean send2(){
amqpTemplate.convertAndSend("fanout","eee","fanout test......");//这里的"eee"可以替换成任何值,但是不能没有
return true;
}
}
消息消费者RabbitMQConsumer.java跟上诉一样不变
测试类TestController.java
package com.springboot_springdatajpa.springdatajpa.controller;
import com.springboot_springdatajpa.springdatajpa.service.RabbitMQProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:39
*/
@RestController
public class TestController {
@Autowired
private RabbitMQProvider rabbitMQProvider;
@RequestMapping("/test")
public boolean sendOne(){
return rabbitMQProvider.send();
}
@RequestMapping("/test2")
public boolean sendFanout(){
return rabbitMQProvider.send2();
}
}
再次启动该项目,浏览器访问http://localhost:8080/test2
控制台输出结果
Topic模式
根据消息的routing key与binding key的匹配关系进行路由,这里可以由多个单次组成,这些单词之间用.隔开。这里允许使通配符:#匹配0个或多个单词
配置类SenderConf .java修改为
package com.springboot_springdatajpa.springdatajpa.interceptor;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:32
*/
@Configuration
public class SenderConf {
// Fanout模式
// @Bean
// public Queue queue(){
// return new Queue("one");
// }
//
// @Bean
// public Queue queue2(){
// return new Queue("two");
// }
// @Bean
// FanoutExchange exchange(){
// return new FanoutExchange("fanout");
// }
//Fanout模式
// @Bean
// Binding bindingExchangeMessage(Queue queue,FanoutExchange fanoutExchange){
// return BindingBuilder.bind(queue).to(fanoutExchange);
// }
// @Bean
// Binding bindingExchangeMessage2(Queue queue2,FanoutExchange exchange){
// return BindingBuilder.bind(queue2).to(exchange);
// }
//topic模式
@Bean(name = "one")
public Queue queue(){
return new Queue("one");
}
@Bean(name = "two")
public Queue queue2(){
return new Queue("two");
}
@Bean
TopicExchange topicExchange(){
return new TopicExchange("exchange");
}
@Bean
Binding bindingExchangeMessage(@Qualifier("one")Queue queue, TopicExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with("topic.#");
}
@Bean
Binding bindingExchangeMessage2(@Qualifier("two")Queue queue,TopicExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with("topic.match");
}
}
消息提供者类RabbitMQProvider .java修改为
package com.springboot_springdatajpa.springdatajpa.service;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:34
*/
@Service
public class RabbitMQProvider {
@Autowired
private AmqpTemplate amqpTemplate;
//direct模式
// public boolean send(){
//
// amqpTemplate.convertAndSend("one","direct test......");
// return true;
// }
//Fanout模式
// public boolean send2(){
// amqpTemplate.convertAndSend("fanout","eee","fanout test......");
//
// return true;
// }
public boolean send1(){
amqpTemplate.convertAndSend("exchange","topic.all","topic-1 test.topic......");
return true;
}
public boolean send2(){
amqpTemplate.convertAndSend("exchange","topic.match","topic-2 topic2......");
return true;
}
}
消息消费者类RabbitMQConsumer.java不变
测试类修改为
package com.springboot_springdatajpa.springdatajpa.controller;
import com.springboot_springdatajpa.springdatajpa.service.RabbitMQProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author zhaomengxia
* @create 2019/8/29 14:39
*/
@RestController
public class TestController {
@Autowired
private RabbitMQProvider rabbitMQProvider;
// @RequestMapping("/test")
// public boolean sendOne(){
// return rabbitMQProvider.send();
// }
//
// @RequestMapping("/test2")
// public boolean sendFanout(){
// return rabbitMQProvider.send2();
// }
@RequestMapping("/testTopicOne")
public boolean sendTOpicOne(){
return rabbitMQProvider.send1();
}
@RequestMapping("/testTopicTwo")
public boolean sendTopicTwo(){
return rabbitMQProvider.send2();
}
}
再次启动该项目,浏览器访问http://localhost:8080/testTopicOne
控制台输出结果为
浏览器访问
控制台输出结果为
从上诉结果可以得知:当routing key为topic.match时,binding key为topic.#和topic.match的one和two队列都能接收到消息;而当routing key为topic.all时,只有binding key为topic.#的one队列才能接收到消息。
上诉实例对RabbitMQ的消息路由进行了简单的演示。对上诉Direct,Fanout,Topic三种常用的Exchange模式及在Springboot中的继承进行了简单的演示。