前言
类的介绍:
- RabbitMqConfig:消息队列配置类,包括拿到application的配置,定义队列,交换机,交换机绑定队列指定routingkey
- RabbitmqSend:消息发送类,使用时直接将此自动注入然后使用,主要的方法就是将消息放入每个routkey指定的队列中
- MsgReceiver:负责接受消息并处理他们
一、RabbitMqConfig
@Configuration
@PropertySource("classpath:application.properties")//指定配置文件
public class RabbitMqConfig {
// @Value("${spring.rabbitmq.host}")
private String host="127.0.0.1";
//@Value("${spring.rabbitmq.port}")
private int port=5672;
//@Value("${spring.rabbitmq.username}")
private String username="guest";
//@Value("${spring.rabbitmq.password}")
private String password="guest";
public static final String EXCHANGE_A = "my-mq-exchange_A";
public static final String EXCHANGE_B = "my-mq-exchange_B";
public static final String QUEUE_A = "QUEUE_A";
public static final String QUEUE_B = "QUEUE_B";
public static final String ROUTINGKEY_A = "spring-boot-routingKey_A";
public static final String ROUTINGKEY_B = "spring-boot-routingKey_B";
//创建连接工厂
@Bean
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost("/");
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//必须是prototype类型
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
/**
* * 针对消费者配置
* * 1. 设置交换机类型
* * 2. 将队列绑定到交换机
* FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念
* HeadersExchange :通过添加属性key-value匹配
* DirectExchange:按照routingkey分发到指定队列
* TopicExchange:多关键字匹配
*/
//声明交换机
@Bean
public DirectExchange defaultExchange() {
return new DirectExchange(EXCHANGE_A);
}
@Bean
public DirectExchange defaultExchange1() {
return new DirectExchange(EXCHANGE_B);
}
//声明队列
@Bean
public Queue queueA() {
return new Queue(QUEUE_A, true); //队列持久:不会随着服务器重启造成丢失
}
@Bean
public Queue queueB() {
return new Queue(QUEUE_B, true); //队列持久
}
//队列绑定交换机,指定routingkey
@Bean
public Binding binding() {
//绑定队列到交换机上通过路由
return BindingBuilder.bind(queueA()).to(defaultExchange()).with(RabbitMqConfig.ROUTINGKEY_A);
}
@Bean
public Binding bindingb() {
return BindingBuilder.bind(queueB()).to(defaultExchange1()).with(RabbitMqConfig.ROUTINGKEY_B);
}
}
二、RabbitmqSend
@Component
public class RabbitmqSend implements RabbitTemplate.ConfirmCallback {
//由于rabbitTemplate的scope属性设置为ConfigurableBeanFactory.SCOPE_PROTOTYPE,所以不能自动注入
private RabbitTemplate rabbitTemplate;
/**
* 构造方法注入rabbitTemplate,config的
*/
@Autowired
public RabbitmqSend(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setConfirmCallback(this); //rabbitTemplate如果为单例的话,那回调就是最后设置的内容
}
public void sendMsg(List<String> content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
//把消息放入ROUTINGKEY_A对应的队列当中去,对应的是队列A
rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_A, content, correlationId);
}
public void sendMsgB(List<String> content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
//把消息放入ROUTINGKEY_B对应的队列当中去,对应的是队列B
rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_B, RabbitMqConfig.ROUTINGKEY_B, content, correlationId);
}
/**
* 回调
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println(" 回调id:" + correlationData);
if (ack) {
System.out.println("消息成功消费");
} else {
System.out.println("消息消费失败:" + cause);
}
}
}
三、MsgReceiver
@Component
@RabbitListener(queues = RabbitMqConfig.QUEUE_A)
public class MsgReceiver {
@RabbitHandler
public void process(List<String> content) {
System.out.println("接收处理队列A当中的消息HASH: " + content);
}
}
四、MsgReceiverB
@Component
@RabbitListener(queues = RabbitMqConfig.QUEUE_B)
public class MsgReceiverB {
private final BaseFileshelfDao baseFileshelfDao;
public MsgReceiverB( BaseFileshelfDao baseFileshelfDao) {
this.baseFileshelfDao = baseFileshelfDao;
}
@RabbitHandler
public void processB(List<String> content) {
String o = (String)content.get(0);
String n=o.substring(2);
System.out.println(n);
baseFileshelfDao.updateGoodsById(n,(String)content.get(1));
System.out.println("接收处理队列B当中的消息HASH: " + content);
}
}
总结
总体来说过程就是那么几个
- 拿出配置文件
- 定义交换机,队列,路由
- 建立连接工厂
- 声明队列
- 绑定交换机与队列的关系
- 发送消息
- 把消息拿出来