diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java index 4cfb540d..3aa26847 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java @@ -638,6 +638,8 @@ public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, Applicat @Override // NOSONAR complexity public void initialize() { + redeclareManualDeclarables(); + if (this.applicationContext == null) { this.logger.debug("no ApplicationContext has been set, cannot auto-declare Exchanges, Queues, and Bindings"); return; @@ -690,6 +692,14 @@ public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, Applicat declareBindings(channel, bindings.toArray(new Binding[bindings.size()])); return null; }); + this.logger.debug("Declarations finished"); + + } + + /** + * Process manual declarables. + */ + private void redeclareManualDeclarables() { if (this.manualDeclarables.size() > 0) { synchronized (this.manualDeclarables) { this.logger.debug("Redeclaring manually declared Declarables"); @@ -706,7 +716,6 @@ public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, Applicat } } } - this.logger.debug("Declarations finished"); } diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java index 9c0f2b8f..b36cc3a0 100644 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java +++ b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java @@ -445,6 +445,52 @@ public class RabbitAdminTests extends NeedsManagementTests { cf.destroy(); } + @Test + void manualDeclarationsWithoutApplicationContext() { + CachingConnectionFactory cf = new CachingConnectionFactory( + RabbitAvailableCondition.getBrokerRunning().getConnectionFactory()); + RabbitAdmin admin = new RabbitAdmin(cf); + admin.setRedeclareManualDeclarations(true); + Map declarables = TestUtils.getPropertyValue(admin, "manualDeclarables", Map.class); + assertThat(declarables).hasSize(0); + RabbitTemplate template = new RabbitTemplate(cf); + // manual declarations + admin.declareQueue(new Queue("test1", false, true, true)); + admin.declareQueue(new Queue("test2", false, true, true)); + admin.declareExchange(new DirectExchange("ex1", false, true)); + admin.declareBinding(new Binding("test1", DestinationType.QUEUE, "ex1", "test", null)); + admin.deleteQueue("test2"); + template.execute(chan -> chan.queueDelete("test1")); + cf.resetConnection(); + admin.initialize(); + assertThat(admin.getQueueProperties("test1")).isNotNull(); + assertThat(admin.getQueueProperties("test2")).isNull(); + assertThat(declarables).hasSize(3); + // verify the exchange and binding were recovered too + template.convertAndSend("ex1", "test", "foo"); + Object received = template.receiveAndConvert("test1", 5000); + assertThat(received).isEqualTo("foo"); + admin.resetAllManualDeclarations(); + assertThat(declarables).hasSize(0); + cf.resetConnection(); + admin.initialize(); + assertThat(admin.getQueueProperties("test1")).isNull(); + admin.declareQueue(new Queue("test1", false, true, true)); + admin.declareExchange(new DirectExchange("ex1", false, true)); + admin.declareBinding(new Binding("test1", DestinationType.QUEUE, "ex1", "test", null)); + admin.declareExchange(new DirectExchange("ex2", false, true)); + admin.declareBinding(new Binding("test1", DestinationType.QUEUE, "ex2", "test", null)); + admin.declareBinding(new Binding("ex1", DestinationType.EXCHANGE, "ex2", "ex1", null)); + assertThat(declarables).hasSize(6); + admin.deleteExchange("ex2"); + assertThat(declarables).hasSize(3); + admin.deleteQueue("test1"); + assertThat(declarables).hasSize(1); + admin.deleteExchange("ex1"); + assertThat(declarables).hasSize(0); + cf.destroy(); + } + @Configuration public static class Config {