动态生产
动态创建队列并绑定交换机,交换机、路由、队列名在实际开发在建议采取动态配置
@Component
public class ExchangeAndQueueConfig {
@Autowired
private RabbitAdmin rabbitAdmin;
/**
* 生成交换机,绑定队列
*
* @param exchange 交换机
* @param routingKey 路由
* @param queueName 队列
*/
public void createDirectBindQueue(String exchange, String routingKey, String queueName) {
//声明
DirectExchange directExchange = new DirectExchange(exchange, true, false);
Queue queue = new Queue(queueName, true, false, false);
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(routingKey);
//创建
rabbitAdmin.declareQueue(queue);
rabbitAdmin.declareExchange(directExchange);
rabbitAdmin.declareBinding(binding);
}
}
往队列发送消息
@Slf4j
@Component
public class SimpleSendDemo {
@Autowired
private ConnectionFactory connectionFactory;
public RabbitTemplate getRabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMandatory(true);
return template;
}
public void sendDirect(String exchange, String routingKey, String msg) {
RabbitTemplate rabbitTemplate = getRabbitTemplate(connectionFactory);
rabbitTemplate.setReturnCallback((message, i, s, s1, s2) -> {
log.error("消息退回:" + message.toString() + "======" + i + "=======" + s1 + "======" + s2);
});
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
if (!ack) {
log.error("消息发送失败:" + cause + correlationData);
} else {
log.info("消息发送成功");
}
});
Message message = MessageBuilder
.withBody(msg.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setContentEncoding("UTF-8")
.setMessageId(UUID.randomUUID().toString()).build();
rabbitTemplate.send(exchange, routingKey, message);
}
}
单元测试
@RunWith(SpringRunner.class)
@WebAppConfiguration
public class ProduceTest {
@Autowired
private SimpleSendDemo simpleSendDemo;
@Autowired
private ExchangeAndQueueConfig exchangeAndQueueConfig;
@Test
public void sendDirect() {
String exchange = "directExchange";
String queueName = "directQueue";
String routingKey = "directExchange.directQueue";
exchangeAndQueueConfig.createDirectBindQueue(exchange, routingKey, queueName);
String message = new Date().toString();
simpleSendDemo.sendDirect(exchange, routingKey, message);
}
}
动态监听
网上大多数文章都采取注解监听式来获取消息,但是在实际开发中多有不便,注解无法动态配置监听哪个队列
动态监听配置类
@Configuration
public class DynamicListenerConfig {
@Autowired
private SimpleDynamicListener simpleDynamicListener;
@Bean("simpleMessageListenerContainer")
public SimpleMessageListenerContainer simpleMessageListenerContainer(CachingConnectionFactory cachingConnectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cachingConnectionFactory);
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setConcurrentConsumers(10);
container.setMaxConcurrentConsumers(10);
container.setMessageListener(simpleDynamicListener);//配置队列监听器
container.start();
return container;
}
消息监听处理类
@Slf4j
@Service
public class SimpleDynamicListener implements ChannelAwareMessageListener {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
String queue = message.getMessageProperties().getConsumerQueue();
byte[] body = message.getBody();
log.info("接收到:" + queue + ",消息内容为:" + new String(body));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info(queue + "队列消息消费成功");
}
}
单元测试
将需要监听的队列放入配置好的监听器内,开始监听
@RunWith(SpringRunner.class)
@WebAppConfiguration
public class ConsumerTes {
@Autowired
@Qualifier("simpleMessageListenerContainer")
private SimpleMessageListenerContainer simpleContainer;
@Test
public void receiveDirect() {
String queueName = "directQueue";
simpleContainer.addQueueNames(queueName);
simpleContainer.start();
}
}