生产者:发送消息;消费者:接收消息;队列:消息中转站
交换机:接受生产者发送的消息并将这些消息路由给服务器中的队列
交换机是有4种类型,这里用到的是topic,这种类型会根据路由键(routingKey)进行模糊匹配
这里对rabbitMQ的原理及作用不做赘述,只讲实战用例
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 生产者
*/
@Component
public class UserSender {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
/**
* convertAndSend
* 参数一:交换机
* 参数二:路由键 这里我们自己定义路由键
* 参数三:消息
* 我们每个生产者发送4种日志类型的消息,便于查看效果
*/
this.amqpTemplate.convertAndSend(this.exchange,"user.log.info","user.log.info....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"user.log.debug","user.log.debug....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"user.log.error","user.log.error....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"user.log.warn","user.log.warn....."+msg);
}
}
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 生产者
*/
@Component
public class ProductSender {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
/**
* convertAndSend
* 参数一:交换机
* 参数二:路由键
* 参数三:消息
*/
this.amqpTemplate.convertAndSend(this.exchange,"product.log.info","product.log.info....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"product.log.debug","product.log.debug....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"product.log.error","product.log.error....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"product.log.warn","product.log.warn....."+msg);
}
}
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 生产者
*/
@Component
public class OrderSender {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
/**
* convertAndSend
* 参数一:交换机
* 参数二:路由键
* 参数三:消息
*/
this.amqpTemplate.convertAndSend(this.exchange,"order.log.info","order.log.info....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"order.log.debug","order.log.debug....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"order.log.error","order.log.error....."+msg);
this.amqpTemplate.convertAndSend(this.exchange,"order.log.warn","order.log.warn....."+msg);
}
}
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
* 消费者(消息接收者)
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列名称
* autoDelete:是否是一个可删除的临时队列
* @Exchange value:为交换器起个名称
* type:指定具体的交换器类型
*/
@Component
@RabbitListener(
bindings =@QueueBinding(
value = @Queue(value = "${mq.config.queue_info_log}",autoDelete = "true"),
//注意看这里,交换机的类型变成了 TOPIC
exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
//注意看这里,路由键设置成了通配符形式,*代表任意字符
key = "*.log.info"
)
)
public class InfosReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("......Info.....Receiver:"+msg);
}
}
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
* 消费者(消息接收者)
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列名称
* autoDelete:是否是一个可删除的临时队列
* @Exchange value:为交换器起个名称
* type:指定具体的交换器类型
*/
@Component
@RabbitListener(
bindings =@QueueBinding(
value = @Queue(value = "${mq.config.queue_error_log}",autoDelete = "true"),
//注意看这里,交换机的类型变成了 TOPIC
exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
//注意看这里,路由键设置成了通配符形式
key = "*.log.error"
)
)
public class ErrorsReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("......Error.....Receiver:"+msg);
}
}
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
/**
* 消费者(消息接收者)
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列名称
* autoDelete:是否是一个可删除的临时队列
* @Exchange value:为交换器起个名称
* type:指定具体的交换器类型
*/
@Component
@RabbitListener(
bindings =@QueueBinding(
value = @Queue(value = "${mq.config.queue_all_log}",autoDelete = "true"),
//注意看这里,交换机的类型变成了 TOPIC
exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.TOPIC),
//注意看这里,路由键设置成了通配符形式
key = "*.log.*"
)
)
public class AllReceiver {
@RabbitHandler
public void process(String msg){
System.out.println(".....All....Receiver:"+msg);
}
}
//注入生产者类
@Autowired
private UserSender userSender;
@Autowired
private ProductSender productSender;
@Autowired
private OrderSender orderSender;
@Test
public void test3(){
this.userSender.send("UserSender...");
this.productSender.send("ProductSender...");
this.orderSender.send("OrderSender...");
}
三个生产者向交换机发送了4条消息,交换机又根据不同的匹配规则向三个消费者发送消息,根据代码我们可以得出,控制台一共可以打印18条信息
不太明白的话,可以单独调用看看输出结果,单独调用一个send方法可以打印6条信息