如何以编程方式将异步使用者订阅到Spring AMQP中的队列?

时间:2014-12-12 13:40:10

标签: java spring spring-amqp

Spring AMQP文档仅显示如何使用~MessageListenerContainer在应用程序初始化时以编程方式订阅队列。

现在代码如下:

public void subscribe(EventType eventType, Object consumer) {
        Assert.notNull(eventType);
        Assert.notNull(eventType.toString());
        Assert.isTrue(!eventType.toString().isEmpty());

        Queue queue=new Queue("", false, true, true);
        Map<String, Exchange> beanMap=context.getBeansOfType(Exchange.class);
        if(beanMap!=null&&!beanMap.isEmpty()){
            Exchange exchange=null;
            boolean found=false;
            for(String key : beanMap.keySet()) {
                exchange=beanMap.get(key);
                if(getExchangeName(eventType.toString()).equals(exchange.getName())){
                    found=true;
                    break;
                }
            }
            if(found){
                amqpAdmin.declareQueue(queue);
                amqpAdmin.declareBinding(new Binding(queue.getName(), Binding.DestinationType.QUEUE, exchange.getName(), "", null));
                SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
                container.setConnectionFactory(connectionFactory);
                container.setQueueNames(queue.getName());
                container.setMessageListener(new MessageListenerAdapter(consumer));
            }else{
                //TODO
            }
        }
    }

由于SimpleMessageListenerContainer是一个生命周期bean,除非在@Configuration bean中使用

,否则它将无法工作

我需要在运行时以编程方式创建订阅,以便bean从队列中获取事件。知道怎么做吗?

2 个答案:

答案 0 :(得分:1)

不清楚你的问题是什么。您可以在运行时创建容器;只需在配置后调用start()即可。有很多测试用例正是如此。

您还可以将队列添加到现有容器中(并删除它们);容器的消费者将被回收以开始从新的队列列表中消费。

答案 1 :(得分:1)

Gary Russells回复是对的,但我的代码仍有一些错误:

  • 如果您创建没有名称的队列,RabbitMQ created 会为其提供一个随机唯一名称。您必须在声明队列时检索它,然后在声明容器和绑定时使用此名称

为清楚起见,我在最终版本中添加了修改后的代码块:

    public void subscribe(EventType eventType, AbstractEventConsumer consumer) {
    Assert.notNull(eventType);
    Assert.notNull(eventType.toString());
    Assert.isTrue(!eventType.toString().isEmpty());

    Queue queue=new Queue("", false, true, true);
    Map<String, Exchange> beanMap=context.getBeansOfType(Exchange.class);
    if(beanMap!=null&&!beanMap.isEmpty()){
        Exchange exchange=null;
        boolean found=false;
        for(String key : beanMap.keySet()) {
            exchange=beanMap.get(key);
            if(getExchangeName(eventType.toString()).equals(exchange.getName())){
                found=true;
                break;
            }
        }
        if(found){
            String queueName=amqpAdmin.declareQueue(queue);
            amqpAdmin.declareBinding(new Binding(queueName, Binding.DestinationType.QUEUE, exchange.getName(), "", null));
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.setQueueNames(queueName);
            container.setMessageListener(new MessageListenerAdapter(consumer));
            container.start();
        }else{
            //TODO
        }
    }
}