From a9b9efa782034556adaa6c190b059f3c09ced093 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 13 Aug 2025 14:15:24 -0400 Subject: [PATCH] GH-10309: Don't register bean for internal `GatewayMH.gatewayProxyFactoryBean` Fixes: https://github.com/spring-projects/spring-integration/issues/10309 The call of the `BeanFactory.initializeBean()` on the internal `GatewayProxyFactoryBean` instance of the `GatewayMessageHandler` causes an extra bean to be processed everywhere. Since such a registration happens from the `GatewayMessageHandler.start()`, the `SpringIntegrationTestExecutionListener#prepareTestInstance` may suffer from a `ConcurrentModificationException` on the `autoStartupCandidates`. Just because its logic is to call `start()` from that `autoStartupCandidates` collection iteration. Essentially, we don't need that since a `GatewayMessageHandler` is a bean itself. The `GatewayProxyFactoryBean` is used internally to avoid logic duplication of the proxy creating on the provided interface. * Rework the logic of the `GatewayMessageHandler` to call all the respective `BeanFactory` call-backs manually. * Add an `IntegrationFlow` bean with a `gateway()` into the `MockMessageHandlerTests` to ensure that `SpringIntegrationTestExecutionListener` does not suffer from a `ConcurrentModificationException` anymore. **Auto-cherry-pick to `6.5.x`** --- .../integration/gateway/GatewayMessageHandler.java | 10 ++++++---- .../integration/test/mock/MockMessageHandlerTests.java | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java index c3dab969860..755ae5055ad 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java @@ -25,7 +25,6 @@ import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.support.management.ManageableLifecycle; @@ -158,9 +157,12 @@ private void initialize() { this.gatewayProxyFactoryBean.setDefaultReplyTimeout(this.replyTimeout); } - if (getBeanFactory() instanceof ConfigurableListableBeanFactory configurableListableBeanFactory) { - configurableListableBeanFactory.initializeBean(this.gatewayProxyFactoryBean, getComponentName() + "#gpfb"); - } + this.gatewayProxyFactoryBean.setBeanName(getComponentName() + "#gpfb"); + this.gatewayProxyFactoryBean.setBeanFactory(getBeanFactory()); + this.gatewayProxyFactoryBean.setApplicationContext(getApplicationContext()); + this.gatewayProxyFactoryBean.setBeanClassLoader(getBeanClassLoader()); + this.gatewayProxyFactoryBean.afterPropertiesSet(); + try { this.exchanger = this.gatewayProxyFactoryBean.getObject(); } diff --git a/spring-integration-test/src/test/java/org/springframework/integration/test/mock/MockMessageHandlerTests.java b/spring-integration-test/src/test/java/org/springframework/integration/test/mock/MockMessageHandlerTests.java index 0c401a02235..09faadd69fa 100644 --- a/spring-integration-test/src/test/java/org/springframework/integration/test/mock/MockMessageHandlerTests.java +++ b/spring-integration-test/src/test/java/org/springframework/integration/test/mock/MockMessageHandlerTests.java @@ -36,6 +36,7 @@ import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.endpoint.ReactiveStreamsConsumer; import org.springframework.integration.expression.ValueExpression; import org.springframework.integration.handler.ExpressionEvaluatingMessageHandler; @@ -365,6 +366,12 @@ public ReactiveMessageHandler reactiveMessageHandler() { return message -> Mono.empty(); } + // Before the fix for https://github.com/spring-projects/spring-integration/issues/10309 this test suite has failed + @Bean + IntegrationFlow flowWithGateway() { + return flow -> flow.gateway(subFlow -> subFlow.bridge()); + } + } }