0

We are using Spring AMQP to connect to RabbitMQ in our Spring based web application.

When we declare our listener-containers as beans (using rabbit:listener-container) in application context, their lifecycle is managed by Spring.

If we declare a listener-container in a component inside a @PostConstruct method, or we create a bean with class org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer as a prototype scoped bean, we then have to manage the lifecycle i.e. start and stop the listener-container ourselves.

My question is, if we declare new queues, bindings and listener-containers inside a @PostConstruct method, just calling listener.stop/shutdown/destroy method inside the corresponding @PreDestroy method would be enough for a graceful shutdown? Or else what do I need to do?

Note: I am guessing I don't have to do anything for the new queues and bindings created in the @PostContruct, but I would be very glad if you also confirm this for me.

nilgun
  • 10,460
  • 4
  • 46
  • 57

1 Answers1

1

I would not recommend starting a listener container or declaring queues/bindings in an @PostConstruct method; the context is only half-baked at that time. It might work but it's not recommended to do stuff like that while the context is being initialized.

It's better to implement SmartLifecycle and start/stop them in the start()/stop() methods.

Then, the container lifecycles would be indirectly managed by the spring context.

You can also control exactly when your bean is started/stopped by putting it in a phase.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks for the answer. I will implement `SmartLifecycle` interface instead of using `@Postconstruct/@PreDestroy`. Also, just calling `stop` on the listener-container will clean up everything gracefully, right? And nothing to be done for queues and bindings? – nilgun Nov 21 '15 at 19:49
  • It depends on what you mean by clean up. If you declare the queue/exchange as auto-delete, they will disappear automatically when the container stops; the queue is deleted first; the exchange is deleted when there are no queues. If you want them to remain between invocations (to avoid losing messages), there is no clean up to do; declaring them next time will be idempotent and you will pick up any messages remaining from the last invocation. If you don't declare them auto-delete and you want them to go away then you will need to delete them (e.g. using RabbitAmin) after stopping the container. – Gary Russell Nov 21 '15 at 20:24
  • 1
    Note that auto-delete can be problematic when you drop connections. Spring-declared queues etc are automatically re-declared when the connection is re-established. Since you are rolling your own for some reason, you will need to handle redeclaring auto-delete items after a connection failure. It's generally easier to just let Spring take care of things for you rather than doing it yourself. – Gary Russell Nov 21 '15 at 20:30