Recently faced a weird issue with Spring AMQP @EventListener
.
Listener was declared like this, so autostartup was set to false
@RabbitListener(id = "MqMessageHandler", queues = "${rabbitMQ.in-queue-name}", autoStartup = "false")
public void receiveMessage(Message message) {
After application is fully initialized and i get a response from some other service, i'm manually starting the listener like this
MessageListenerContainer mqMessageHandler = registry.getListenerContainer(HANDLER_ID);
mqMessageHandler.start();
But it appears that listener is still starting on context initialization.
Digging a bit in the code i found this piece of code inside RabbitListenerEndpointRegistry
/**
* Start the specified {@link MessageListenerContainer} if it should be started
* on startup or when start is called explicitly after startup.
* @param listenerContainer the container.
* @see MessageListenerContainer#isAutoStartup()
*/
private void startIfNecessary(MessageListenerContainer listenerContainer) {
if (this.contextRefreshed || listenerContainer.isAutoStartup()) {
listenerContainer.start();
}
}
That means that listener will be started once ContextRefreshed
event is fired.
I'd expect the condition to be
this.contextRefreshed && listenerContainer.isAutoStartup()
so &&
instead of ||
and then it should work as expected.
Does anybody knows if the condition is correct, and my assumptions are wrong?
Spring AMQP version is 2.3.1
but the same i saw in 2.3.10
As a workaround for now i'm registering listener manually like this
MessageListenerContainer mqMessageHandler = registry.getListenerContainer(HANDLER_ID);
if (Objects.isNull(mqMessageHandler)) {
SimpleRabbitListenerEndpoint endpoint = new SimpleRabbitListenerEndpoint();
endpoint.setQueueNames(inQueueName);
endpoint.setMessageListener(this.mqMessageHandler);
endpoint.setId(HANDLER_ID);
registry.registerListenerContainer(endpoint, factory);
mqMessageHandler = registry.getListenerContainer(HANDLER_ID);
}
mqMessageHandler.start();
So after investigation it was found that:
context.refresh()
and context.start()
was called manually from the code of in-hous platform. In that case contextRefreshed
flag in RabbitListenerEndpointRegistry
was set to true, and during 2nd call to startIfNecessary
(beacause of context.start()
) listener was started.