【问题标题】:Declaration of exchanges and queues in Spring AMQPSpring AMQP中交换和队列的声明
【发布时间】:2010-10-06 12:58:55
【问题描述】:

我正在使用 RabbitMQ 并尝试将我当前的本机 Java 实现重构为使用 Spring AMQP 抽象。

使用 Spring 库声明交换、队列及其绑定是通过 AMQPAdmin 接口进行的,但我不确定何时应该进行这种配置。

我有一个使用 Rabbit 生成消息的 Web 应用程序。另一个使用这些消息的应用程序。令人震惊:)

但是什么时候显示交换/队列的声明?

我是否将 AMQPAdmin 与 Web 应用程序一起部署并在生产者和消费者的构造函数中进行交换/队列管理?

这些事情的声明是一次性的,broken 不需要再次知道它们,所以任何代码在后续执行中都是 NOOP。

我要创建一个单独的应用程序来管理代理吗?

目前的想法或最佳实践是什么?

【问题讨论】:

    标签: spring messaging


    【解决方案1】:

    似乎很少有人在使用 Spring 的 AMQP M1 版本,所以我将用我所做的来回答我自己的问题。

    在生产者的构造函数中,我声明了交换。然后在 RabbitTemplate 上设置交换。我还将 RabbitTemplate 上的路由键设置为队列名称,但这不是必需的,但这是我将使用的路由。

    @Service("userService")
    public class UserService {
        private final RabbitTemplate rabbitTemplate;
    
        @Autowired
        public UserService(final RabbitAdmin rabbitAdmin,
                           final Exchange exchange,
                           final Queue queue,
                           @Qualifier("appRabbitTemplate") final RabbitTemplate rabbitTemplate) {
    
            this.rabbitTemplate = rabbitTemplate;
    
            rabbitAdmin.declareExchange(exchange);
            rabbitTemplate.setExchange(exchange.getName());
            rabbitTemplate.setRoutingKey(queue.getName());  
        }
    
    
        public void createAccount(final UserAccount userAccount) {
            rabbitTemplate.convertAndSend("Hello message sent at " + new DateTime());
        }
    }
    

    在消费者的构造函数中,我声明了队列并创建了绑定。

    public class Consumer implements ChannelAwareMessageListener<Message> {
    
        public Consumer(final RabbitAdmin rabbitAdmin, final Exchange exchange, final Queue queue) {
            rabbitAdmin.declareQueue(queue);
    
            rabbitAdmin.declareBinding(BindingBuilder.from(queue).to((DirectExchange) exchange).withQueueName());
        }
    
        @Override
        public void onMessage(Message message, Channel channel) throws Exception {
    
            System.out.println(new String(message.getBody()));
    
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        }
    }
    

    虽然构造函数可能会运行多次,但 RabbitMQ 只声明了一次交换、队列和绑定。

    如果您需要这个小示例项目的完整源代码,请提出要求,我会在某个地方为您提供。

    【讨论】:

    • 拜托了!我很想看看你是如何做这一切的,因为我现在正在努力解决这个问题。
    • @dom farr 、Spring Messaging for RabbitMQrabbitTemplatequeueexchangebinding 均由 Spring Boot 设置。我不明白rabbitTemplate.convertAndSend(...) 如何将它发送到创建的交换,因为方法调用没有指定任何交换,只有路由键(通过队列名称) - 我认为它隐式发送到默认交换而不是创建的交易所。
    • @WebUser 快速查看文档可以看到配置文件中为交换、队列和绑定定义的bean。然后 Spring boot 创建 RabbitTemplate 它将使用这些 bean。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    相关资源
    最近更新 更多