直接开始撸代码
都是参考别的大佬写的,这里自己记录下,虽然网上的教程一大堆了,但是自己写个小demo记录一下,做个备忘录。方便后期查找
通过eclipse或者sts新建一个springboot项目,添加rabbitMQ依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
application.properties配置文件
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=hll
spring.rabbitmq.password=hll123
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.virtual-host=/hll
开始rabbitMQ的实现
一、单生产者和单消费者
创建一个队列,新建一个配置类RabbitmqConfig,后面的队列,交换机绑定都写着里面
@Bean
public Queue helloQueue() {
return new Queue("hello-rabbit");
}
创建一个生产者
@Component
public class RabbitSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send() {
String context = "hello rabbit " + new Date();
System.out.println("Sender:" + context);
this.amqpTemplate.convertAndSend("hello-rabbit", context);
}
}
创建一个消费者
@Component
@RabbitListener(queues = "hello-rabbit")
public class RabbitReceiver {
@RabbitHandler
public void process(String context) {
System.out.println("Receiver:" + context);
}
}
开始测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private RabbitSender rabbitSender;
@Test
public void helloRabbit() {
rabbitSender.send();
}
}
会在控制台看到receiver接收到了sender生产的消息
二、单生产者和多消费者
创建一个队列
@Bean
public Queue ManyReceiver() {
return new Queue("many-receiver");
}
创建一个生产者
@Component
public class RabbitSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(int i) {
String context = "hello rabbit " + i;
System.out.println("Sender:" + context);
this.amqpTemplate.convertAndSend("many-receiver", context);
}
}
创建两个消费者
@Component
@RabbitListener(queues = "many-receiver")
public class Receiver1 {
@RabbitHandler
public void process(String context) {
System.out.println("Receiver1:" + context);
}
}
@Component
@RabbitListener(queues = "many-receiver")
public class Receiver2 {
@RabbitHandler
public void process(String context) {
System.out.println("Receiver2:" + context);
}
}
开始测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private RabbitSender rabbitSender;
@Test
public void helloRabbit() throws InterruptedException {
for (int i=0; i<10; i++) {
//Thread.sleep(10);
rabbitSender.send(i);
}
}
}
通过控制台可以看到消息均匀的被两个消费者消费了
三、多生产者和多消费者
创建一个队列
@Bean
public Queue ManySenderAndReceiver() {
return new Queue("many-sender-receiver");
}
创建两个生产者
@Component
public class Sender1 {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(int i) {
String context = "sender1:" +i;
System.out.println("sender1:" + context);
this.amqpTemplate.convertAndSend("many-sender-receiver", context);
}
}
@Component
public class Sender2 {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(int i) {
String context = "sender2:" +i;
System.out.println("sender2:" + context);
this.amqpTemplate.convertAndSend("many-sender-receiver", context);
}
}
创建两个消费者
@Component
@RabbitListener(queues = "many-sender-receiver")
public class Receiver3 {
@RabbitHandler
public void process(String context) {
System.out.println("Receiver3:" + context);
}
}
@Component
@RabbitListener(queues = "many-sender-receiver")
public class Receiver4 {
@RabbitHandler
public void process(String context) {
System.out.println("Receiver4:" + context);
}
}
开始测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private Sender1 sender1;
@Autowired
private Sender2 sender2;
@Test
public void manySenderReceiver() {
for (int i=0; i<5; i++) {
sender1.send(i);
sender2.send(i);
}
}
}
控制台打印如下:
四、对象信息
创建实体类
public class User implements Serializable {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
新建生产者
@Component
public class UserSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(User user) {
System.out.println("sender:" + user.toString());
this.amqpTemplate.convertAndSend("user-queue", user);
}
}
新建消费者
@Component
@RabbitListener(queues = "user-queue")
public class UserReceiver {
@RabbitHandler
public void process(User user) {
System.out.println("receiver:" + user.toString());
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private UserSender userSender;
@Test
public void userRabbit() {
User user = new User();
user.setUsername("hll");
user.setPassword("123456");
//System.out.println(user.toString());
userSender.send(user);
}
}
控制台输出:
五、topic ExChange
topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列
新建两个队列,一个交换机,再绑定队列到交换机上
final static String message = "topic.message";
final static String messages = "topic.messages";
@Bean
public Queue queueMessage() {
return new Queue(RabbitmqConfig.message);
}
@Bean
public Queue queueMessages() {
return new Queue(RabbitmqConfig.messages);
}
/**
* 交换机
* @return
*/
@Bean
public TopicExchange exchange() {
return new TopicExchange("topicExchange");
}
/**
* 将队列topic.message与exchange绑定,binding_key为topic.message
* @param queueMessage 这个队列参数名需要和上面创建的队列方法名一样
* @param exchange
* @return
*/
@Bean
public Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
}
/**
* 将topic.messages与exchange绑定,binding_key为topic.#,模糊匹配,前缀匹配到topic.即可
* @param queueMessages 这个队列参数名需要和上面创建的队列方法名一样
* @param exchange
* @return
*/
@Bean
public Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
}
新建生产者
@Component
public class TopicSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send1() {
String context = "this routing-key is topic.message";
System.out.println("sender:" + context);
this.amqpTemplate.convertAndSend("topicExchange", "topic.message", context);
}
public void send2() {
String context = "this routing-key is topic.messages";
System.out.println("sender:" +context);
this.amqpTemplate.convertAndSend("topicExchange", "topic.messages", context);
}
}
新建消费者
@Component
@RabbitListener(queues = "topic.message")
public class TopicReceiver1 {
@RabbitHandler
public void process(String message) {
System.out.println("TopicReceiver1:" + message);
}
}
@Component
@RabbitListener(queues = "topic.messages")
public class TopicReceiver2 {
@RabbitHandler
public void process(String message) {
System.out.println("TopicReceiver2:" + message);
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private TopicSender topicSender;
@Test
public void topic() {
topicSender.send1();
//topicSender.send2();
}
}
topic.send()结果如下
send1的routing-key是 topic.message 通过config里面交换机绑定配置的规则,topic.message满足topic.#,topic.message两个绑定规则,所以两个队列都能收到这个消息
send2的routing-key是topic.messages,只满足topic.#这一个规则,所以只有top[ic.messages这个队列可以接收到消息
六、fanout ExChange
给 Fanout 交换机发送消息,绑定了这个交换机的所有队列都会收到这个消息,发送端的 routing_key即便指定 了队列名称也会被忽略
新建队列和fanout交换机
//三个队列
@Bean
public Queue AQueue() {
return new Queue("fanout.A");
}
@Bean
public Queue BQueue() {
return new Queue("fanout.B");
}
@Bean
public Queue CQueue() {
return new Queue("fanout.C");
}
//fanout交换机
/**
* fanoutExchange 交换机
* @return
*/
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
//绑定队列和fanout交换机
@Bean
public Binding bindingExchangeA(Queue AQueue, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(AQueue).to(fanoutExchange);
}
@Bean
public Binding bindingExchangeB(Queue BQueue, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(BQueue).to(fanoutExchange);
}
@Bean
public Binding bindingExchangeC(Queue CQueue, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(CQueue).to(fanoutExchange);
}
新建生产者
@Component
public class FanoutSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send() {
String context = "this is fanout message";
System.out.println("fanout sender: " +context);
this.amqpTemplate.convertAndSend("fanoutExchange", "test", context);
}
}
新建消费者三个消费者
@Component
@RabbitListener(queues = "fanout.A")
public class FanoutReceiverA {
@RabbitHandler
public void process(String message) {
System.out.println("fanout receiver A:" + message);
}
}
@Component
@RabbitListener(queues = "fanout.B")
public class FanoutReceiverB {
@RabbitHandler
public void process(String message) {
System.out.println("fanout receiver B:" + message);
}
}
@Component
@RabbitListener(queues = "fanout.C")
public class FanoutReceiverC {
@RabbitHandler
public void process(String message) {
System.out.println("fanout receiver C:" + message);
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqApplicationTests {
@Autowired
private FanoutSender fanoutSender;
@Test
public void fanout() {
fanoutSender.send();
}
}
控制台输出如下:
三个消费者都接收到了消息
博客参考:
纯洁的微笑:springboot(八):RabbitMQ详解
SpringBoot+RabbitMq实现生产者与消费者的多种情景