Skip to content

Commit f71df79

Browse files
committed
GH-3192: Fix RabbitAdmin to avoid eager beans loading
Fixes: #3192 The `RabbitAdmin.initialize()` method calls `applicationContext.getBeansOfType(Declarable.class, false, true);` The third parameter `allowEagerInit = true` causes Spring to eagerly instantiate all `FactoryBean` instances in the application context — even those marked with `lazy-init="true"` — in order to determine their types. * Fix `RabbitAdmin` and `RabbitListenerAnnotationBeanPostProcessor` to use `getBeansOfType(AClass.class, false, false)` to avoid eagerness for lazy-init
1 parent bef4775 commit f71df79

File tree

4 files changed

+37
-39
lines changed

4 files changed

+37
-39
lines changed

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public void afterSingletonsInstantiated() {
261261

262262
if (this.beanFactory instanceof ListableBeanFactory lbf) {
263263
Map<String, RabbitListenerConfigurer> instances =
264-
lbf.getBeansOfType(RabbitListenerConfigurer.class);
264+
lbf.getBeansOfType(RabbitListenerConfigurer.class, false, false);
265265
for (RabbitListenerConfigurer configurer : instances.values()) {
266266
configurer.configureRabbitListeners(this.registrar);
267267
}

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,13 +663,13 @@ private void redeclareBeanDeclarables() {
663663

664664
this.logger.debug("Initializing declarations");
665665
Collection<Exchange> contextExchanges = new LinkedList<>(
666-
this.applicationContext.getBeansOfType(Exchange.class).values());
666+
this.applicationContext.getBeansOfType(Exchange.class, false, false).values());
667667
Collection<Queue> contextQueues = new LinkedList<>(
668-
this.applicationContext.getBeansOfType(Queue.class).values());
668+
this.applicationContext.getBeansOfType(Queue.class, false, false).values());
669669
Collection<Binding> contextBindings = new LinkedList<>(
670-
this.applicationContext.getBeansOfType(Binding.class).values());
670+
this.applicationContext.getBeansOfType(Binding.class, false, false).values());
671671
Collection<DeclarableCustomizer> customizers =
672-
this.applicationContext.getBeansOfType(DeclarableCustomizer.class).values();
672+
this.applicationContext.getBeansOfType(DeclarableCustomizer.class, false, false).values();
673673

674674
processDeclarables(contextExchanges, contextQueues, contextBindings);
675675

@@ -757,7 +757,7 @@ public Set<Declarable> getManualDeclarableSet() {
757757
private void processDeclarables(Collection<Exchange> contextExchanges, Collection<Queue> contextQueues,
758758
Collection<Binding> contextBindings) {
759759

760-
Collection<Declarables> declarables = this.applicationContext.getBeansOfType(Declarables.class, false, true)
760+
Collection<Declarables> declarables = this.applicationContext.getBeansOfType(Declarables.class, false, false)
761761
.values();
762762
declarables.forEach(d -> {
763763
d.getDeclarables().forEach(declarable -> {

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public void testFailOnFirstUseWithMissingBroker() {
134134
rabbitAdmin.setApplicationContext(applicationContext);
135135
rabbitAdmin.setAutoStartup(true);
136136
rabbitAdmin.afterPropertiesSet();
137-
assertThatIllegalArgumentException().isThrownBy(() -> rabbitAdmin.declareQueue());
137+
assertThatIllegalArgumentException().isThrownBy(rabbitAdmin::declareQueue);
138138
connectionFactory.destroy();
139139
}
140140

@@ -153,8 +153,7 @@ public void testProperties() throws Exception {
153153
channel.basicConsume(queueName, true, consumer);
154154
await("Message count > 0").until(() -> messageCount(rabbitAdmin, queueName) == 0);
155155
Properties props = rabbitAdmin.getQueueProperties(queueName);
156-
assertThat(props.get(RabbitAdmin.QUEUE_CONSUMER_COUNT)).isNotNull();
157-
assertThat(props.get(RabbitAdmin.QUEUE_CONSUMER_COUNT)).isEqualTo(1);
156+
assertThat(props).containsEntry(RabbitAdmin.QUEUE_CONSUMER_COUNT, 1);
158157
channel.close();
159158
}
160159
finally {
@@ -170,23 +169,23 @@ private int messageCount(RabbitAdmin rabbitAdmin, String queueName) {
170169
}
171170

172171
@Test
173-
public void testTemporaryLogs() throws Exception {
172+
public void testTemporaryLogs() {
174173
SingleConnectionFactory connectionFactory = new SingleConnectionFactory();
175174
connectionFactory.setHost("localhost");
176175
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
177176
try {
178-
ApplicationContext ctx = mock(ApplicationContext.class);
179-
Map<String, Queue> queues = new HashMap<String, Queue>();
177+
ApplicationContext ctx = mock();
178+
Map<String, Queue> queues = new HashMap<>();
180179
queues.put("nonDurQ", new Queue("testq.nonDur", false, false, false));
181180
queues.put("adQ", new Queue("testq.ad", true, false, true));
182181
queues.put("exclQ", new Queue("testq.excl", true, true, false));
183182
queues.put("allQ", new Queue("testq.all", false, true, true));
184-
given(ctx.getBeansOfType(Queue.class)).willReturn(queues);
185-
Map<String, Exchange> exchanges = new HashMap<String, Exchange>();
183+
given(ctx.getBeansOfType(Queue.class, false, false)).willReturn(queues);
184+
Map<String, Exchange> exchanges = new HashMap<>();
186185
exchanges.put("nonDurEx", new DirectExchange("testex.nonDur", false, false));
187186
exchanges.put("adEx", new DirectExchange("testex.ad", true, true));
188187
exchanges.put("allEx", new DirectExchange("testex.all", false, true));
189-
given(ctx.getBeansOfType(Exchange.class)).willReturn(exchanges);
188+
given(ctx.getBeansOfType(Exchange.class, false, false)).willReturn(exchanges);
190189
rabbitAdmin.setApplicationContext(ctx);
191190
rabbitAdmin.afterPropertiesSet();
192191
Log logger = spy(TestUtils.getPropertyValue(rabbitAdmin, "logger", Log.class));
@@ -247,17 +246,17 @@ public void testMultiEntities() {
247246
assertThat(admin.getQueueProperties(ctx.getBean(Config.class).prototypeQueueName)).isNull();
248247
Declarables mixedDeclarables = ctx.getBean("ds", Declarables.class);
249248
assertThat(mixedDeclarables.getDeclarablesByType(Queue.class))
250-
.hasSize(1)
251-
.extracting(Queue::getName)
252-
.contains("q4");
249+
.hasSize(1)
250+
.extracting(Queue::getName)
251+
.contains("q4");
253252
assertThat(mixedDeclarables.getDeclarablesByType(Exchange.class))
254-
.hasSize(1)
255-
.extracting(Exchange::getName)
256-
.contains("e4");
253+
.hasSize(1)
254+
.extracting(Exchange::getName)
255+
.contains("e4");
257256
assertThat(mixedDeclarables.getDeclarablesByType(Binding.class))
258-
.hasSize(1)
259-
.extracting(Binding::getDestination)
260-
.contains("q4");
257+
.hasSize(1)
258+
.extracting(Binding::getDestination)
259+
.contains("q4");
261260
ctx.close();
262261
}
263262

@@ -283,14 +282,13 @@ public void testAvoidHangAMQP_508() {
283282

284283
@Test
285284
public void testIgnoreDeclarationExceptionsTimeout() throws Exception {
286-
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = mock(
287-
com.rabbitmq.client.ConnectionFactory.class);
285+
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = mock();
288286
TimeoutException toBeThrown = new TimeoutException("test");
289287
willThrow(toBeThrown).given(rabbitConnectionFactory).newConnection(any(ExecutorService.class), anyString());
290288
CachingConnectionFactory ccf = new CachingConnectionFactory(rabbitConnectionFactory);
291289
ccf.setExecutor(mock(ExecutorService.class));
292290
RabbitAdmin admin = new RabbitAdmin(ccf);
293-
List<DeclarationExceptionEvent> events = new ArrayList<DeclarationExceptionEvent>();
291+
List<DeclarationExceptionEvent> events = new ArrayList<>();
294292
admin.setApplicationEventPublisher(new EventPublisher(events));
295293
admin.setIgnoreDeclarationExceptions(true);
296294
admin.declareQueue(new AnonymousQueue());
@@ -313,13 +311,13 @@ public void testIgnoreDeclarationExceptionsTimeout() throws Exception {
313311

314312
@Test
315313
public void testWithinInvoke() throws Exception {
316-
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
317-
Connection connection = mock(Connection.class);
314+
ConnectionFactory connectionFactory = mock();
315+
Connection connection = mock();
318316
given(connectionFactory.createConnection()).willReturn(connection);
319-
Channel channel1 = mock(Channel.class);
320-
Channel channel2 = mock(Channel.class);
317+
Channel channel1 = mock();
318+
Channel channel2 = mock();
321319
given(connection.createChannel(false)).willReturn(channel1, channel2);
322-
DeclareOk declareOk = mock(DeclareOk.class);
320+
DeclareOk declareOk = mock();
323321
given(channel1.queueDeclare()).willReturn(declareOk);
324322
given(declareOk.getQueue()).willReturn("foo");
325323
RabbitTemplate template = new RabbitTemplate(connectionFactory);
@@ -339,14 +337,14 @@ public void testWithinInvoke() throws Exception {
339337

340338
@Test
341339
public void testRetry() throws Exception {
342-
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = mock(com.rabbitmq.client.ConnectionFactory.class);
343-
com.rabbitmq.client.Connection connection = mock(com.rabbitmq.client.Connection.class);
340+
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = mock();
341+
com.rabbitmq.client.Connection connection = mock();
344342
given(rabbitConnectionFactory.newConnection((ExecutorService) isNull(), anyString())).willReturn(connection);
345-
Channel channel = mock(Channel.class);
343+
Channel channel = mock();
346344
given(connection.createChannel()).willReturn(channel);
347345
given(channel.isOpen()).willReturn(true);
348346
willThrow(new RuntimeException()).given(channel)
349-
.queueDeclare(anyString(), anyBoolean(), anyBoolean(), anyBoolean(), any());
347+
.queueDeclare(anyString(), anyBoolean(), anyBoolean(), anyBoolean(), any());
350348
CachingConnectionFactory ccf = new CachingConnectionFactory(rabbitConnectionFactory);
351349
RabbitAdmin admin = new RabbitAdmin(ccf);
352350
RetryTemplate rtt = new RetryTemplate();
@@ -359,13 +357,13 @@ public void testRetry() throws Exception {
359357
ctx.getBeanFactory().initializeBean(admin, "admin");
360358
ctx.refresh();
361359
assertThatThrownBy(() -> ccf.createConnection())
362-
.isInstanceOf(UncategorizedAmqpException.class);
360+
.isInstanceOf(UncategorizedAmqpException.class);
363361
ctx.close();
364362
verify(channel, times(3)).queueDeclare(anyString(), anyBoolean(), anyBoolean(), anyBoolean(), any());
365363
}
366364

367365
@Test
368-
public void testLeaderLocator() throws Exception {
366+
public void testLeaderLocator() {
369367
CachingConnectionFactory cf = new CachingConnectionFactory(
370368
RabbitAvailableCondition.getBrokerRunning().getConnectionFactory());
371369
RabbitAdmin admin = new RabbitAdmin(cf);

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitTemplateTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ public void testNestedTxBinding() throws Exception {
444444
rabbitTemplate.setChannelTransacted(true);
445445
RabbitAdmin admin = new RabbitAdmin(rabbitTemplate);
446446
ApplicationContext ac = mock(ApplicationContext.class);
447-
willReturn(Collections.singletonMap("foo", new Queue("foo"))).given(ac).getBeansOfType(Queue.class);
447+
willReturn(Collections.singletonMap("foo", new Queue("foo"))).given(ac).getBeansOfType(Queue.class, false, false);
448448
admin.setApplicationContext(ac);
449449
admin.afterPropertiesSet();
450450
AtomicReference<Channel> templateChannel = new AtomicReference<>();

0 commit comments

Comments
 (0)