1. 程式人生 > 其它 >springboot 整合 rabbitmq時,容器中注入exchange,queue Bean但rabbitmq server 未建立的原因

springboot 整合 rabbitmq時,容器中注入exchange,queue Bean但rabbitmq server 未建立的原因

技術標籤:rabbitmqspring cloud alibaba

public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, ApplicationEventPublisherAware,
		BeanNameAware, InitializingBean

RabbitAdmin implements InitializingBean
在afterPropertiesSet方法中發現,建立queue exchange 的原理

			this.connectionFactory.addConnectionListener
(connection -> { if (!initializing.compareAndSet(false, true)) { // If we are already initializing, we don't need to do it again... return; } try { /* * ...but it is possible for this to happen twice in the same ConnectionFactory (if more than * one concurrent Connection is allowed). It's idempotent, so no big deal (a bit of network * chatter). In fact it might even be a good thing: exclusive queues only make sense if they are * declared for every connection. If anyone has a problem with it: use auto-startup="false". */
if (this.retryTemplate != null) { this.retryTemplate.execute(c -> { initialize(); return null; }); } else { initialize(); } } finally { initializing.compareAndSet(true, false); } });

initialize 中的

		this.rabbitTemplate.execute
(channel -> { declareExchanges(channel, exchanges.toArray(new Exchange[exchanges.size()])); declareQueues(channel, queues.toArray(new Queue[queues.size()])); declareBindings(channel, bindings.toArray(new Binding[bindings.size()])); return null; });

因為

/**
 * A listener for connection creation and closing.
 *
 * @author Dave Syer
 * @author Gary Russell
 *
 */
@FunctionalInterface
public interface ConnectionListener

rabbitmq connection 啟動時不會建立。因此ConnectionListener不會被觸發
initialize 不會被呼叫

解決方案
@Bean
ApplicationRunner runner(ConnectionFactory cf) {
return args -> cf.createConnection().close();
}
OR
@RabbitListener(queues = “temp”)

使其觸發ConnectionListener

Reference:
https://stackoverflow.com/questions/64857283/spring-amqp-rabbitmq-connection-is-not-created-on-application-startup