springboot整合rabbitmq动态生产、动态消费

2,657 阅读1分钟

动态生产

动态创建队列并绑定交换机,交换机、路由、队列名在实际开发在建议采取动态配置

@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();     
    }
    
}