简体   繁体   中英

Spring AMQP Rabbit listener firing before "ApplicationReadyEvent"

On Spring application start up I would like to look up a value in Redis and depending on that value I would like to turn off or leave on the message listeners I have.

It is also possible to not initialize these beans at all, but I cannot find a way to do either.

At the moment, I'm attempting to turn shutdown the containers using Spring's ApplicationReadyEvent :

@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {

    private @Autowired @Qualifier("completedOrderContainer") SimpleMessageListenerContainer container;
    private @Autowired RedisManagerImpl redis;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        if (!Boolean.valueOf(redis.isRabbitListenerActive())) container.shutdown();
    }

}

Container & AMQP beans are initialized as so:

    @Bean
    @Conditional(RabbitCondition.class)
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(rabbitHost + ":" + rabbitPort);
        connectionFactory.setUsername(rabbitUsername);
        connectionFactory.setPassword(rabbitPassword);
        return connectionFactory;
    }

    @Bean
    @Conditional(RabbitCondition.class)
    Queue completedOrderQueue() {
        return new Queue(completedOrderQueueName, true);
    }

    @Bean
    @Conditional(RabbitCondition.class)
    TopicExchange completedOrderExchange() {
        return new TopicExchange(completedOrderExchangeName);
    }

    @Bean
    @Conditional(RabbitCondition.class)
    Binding binding(Queue completedOrderQueue, TopicExchange completedOrderExchange) {
        return BindingBuilder.bind(completedOrderQueue).to(completedOrderExchange).with(completedOrderQueueName);
    }

    @Bean
    @Conditional(RabbitCondition.class)
    SimpleMessageListenerContainer completedOrderContainer(ConnectionFactory connectionFactory, MessageListenerAdapter completedOrderListenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(completedOrderQueueName);
        container.setMessageListener(completedOrderListenerAdapter);
        return container;
    }

    @Bean
    @Conditional(RabbitCondition.class)
    MessageListenerAdapter completedOrderListenerAdapter(CompletedOrderMessageReceiver receiver) {
        return new MessageListenerAdapter(receiver, "completedOrder");
    }

Message listener:

@Component
public class CompletedOrderMessageReceiver {
    public void completedOrder(Object asyncTask) throws Exception {
        //impl
    }
}

The problem is, if I start up the application with a message already in queue, the message listener will pick up the message before container.shutdown() is executed.

Is there a way to achieve my goal? Even with a different approach

Set autoStartup to false on the listener container(s). Then start() and stop() them as needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM