Skip to content

Commit adbbca1

Browse files
artembilangaryrussell
authored andcommitted
INT-4513: Clean IntManageConf from removed beans
JIRA: https://jira.spring.io/browse/INT-4513 The `IntegrationManagementConfigurer` keeps metrics beans in its local stores. When we add beans at runtime, they are not removed from those caches after their removal * Implement `DestructionAwareBeanPostProcessor` in the `IntegrationManagementConfigurer` and clean up caches according provided bean type and its name * Improve `ManualFlowTests` and `FtpTests` to be sure that `IntegrationManagementConfigurer` caches are cleared after destroying `IntegrationFlowRegistration` **Cherry-pick to 5.0.x**
1 parent bd0fd50 commit adbbca1

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.springframework.beans.BeansException;
2828
import org.springframework.beans.factory.BeanNameAware;
2929
import org.springframework.beans.factory.SmartInitializingSingleton;
30-
import org.springframework.beans.factory.config.BeanPostProcessor;
30+
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
3131
import org.springframework.context.ApplicationContext;
3232
import org.springframework.context.ApplicationContextAware;
3333
import org.springframework.integration.core.MessageSource;
@@ -64,8 +64,9 @@
6464
* @since 4.2
6565
*
6666
*/
67-
public class IntegrationManagementConfigurer implements SmartInitializingSingleton, ApplicationContextAware,
68-
BeanNameAware, BeanPostProcessor {
67+
public class IntegrationManagementConfigurer
68+
implements SmartInitializingSingleton, ApplicationContextAware, BeanNameAware,
69+
DestructionAwareBeanPostProcessor {
6970

7071
private static final Log logger = LogFactory.getLog(IntegrationManagementConfigurer.class);
7172

@@ -246,7 +247,8 @@ public void afterSingletonsInstantiated() {
246247
this.metricsFactory = new DefaultMetricsFactory();
247248
}
248249
this.sourceConfigurers.putAll(this.applicationContext.getBeansOfType(MessageSourceMetricsConfigurer.class));
249-
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
250+
Map<String, IntegrationManagement> managed = this.applicationContext
251+
.getBeansOfType(IntegrationManagement.class);
250252
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
251253
IntegrationManagement bean = entry.getValue();
252254
if (!bean.getOverrides().loggingConfigured) {
@@ -259,7 +261,8 @@ public void afterSingletonsInstantiated() {
259261
}
260262

261263
private void injectCaptor() {
262-
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
264+
Map<String, IntegrationManagement> managed = this.applicationContext
265+
.getBeansOfType(IntegrationManagement.class);
263266
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
264267
IntegrationManagement bean = entry.getValue();
265268
if (!bean.getOverrides().loggingConfigured) {
@@ -280,6 +283,30 @@ public Object postProcessAfterInitialization(Object bean, String beanName) throw
280283
return bean;
281284
}
282285

286+
@Override
287+
public boolean requiresDestruction(Object bean) {
288+
return bean instanceof MessageChannelMetrics ||
289+
bean instanceof MessageHandlerMetrics ||
290+
bean instanceof MessageSourceMetrics;
291+
}
292+
293+
@Override
294+
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
295+
if (bean instanceof MessageChannelMetrics) {
296+
this.channelsByName.remove(beanName);
297+
}
298+
else if (bean instanceof MessageHandlerMetrics) {
299+
if (this.handlersByName.remove(beanName) == null) {
300+
this.handlersByName.remove(beanName + ".handler");
301+
}
302+
}
303+
else if (bean instanceof MessageSourceMetrics) {
304+
if (this.sourcesByName.remove(beanName) == null) {
305+
this.sourcesByName.remove(beanName + ".source");
306+
}
307+
}
308+
}
309+
283310
private Object doConfigureMetrics(Object bean, String name) {
284311
if (bean instanceof MessageChannelMetrics) {
285312
configureChannelMetrics(name, (MessageChannelMetrics) bean);

spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@
6060
import org.springframework.context.annotation.Scope;
6161
import org.springframework.integration.channel.QueueChannel;
6262
import org.springframework.integration.config.EnableIntegration;
63+
import org.springframework.integration.config.EnableIntegrationManagement;
6364
import org.springframework.integration.config.EnableMessageHistory;
65+
import org.springframework.integration.config.IntegrationManagementConfigurer;
6466
import org.springframework.integration.core.MessageProducer;
6567
import org.springframework.integration.core.MessagingTemplate;
6668
import org.springframework.integration.dsl.IntegrationFlow;
@@ -114,6 +116,9 @@ public class ManualFlowTests {
114116
@Autowired
115117
private SmartLifecycleRoleController roleController;
116118

119+
@Autowired
120+
private IntegrationManagementConfigurer integrationManagementConfigurer;
121+
117122
@Test
118123
@SuppressWarnings("unchecked")
119124
public void testWithAnonymousMessageProducerStart() {
@@ -128,9 +133,11 @@ protected void doStart() {
128133

129134
};
130135
QueueChannel channel = new QueueChannel();
136+
channel.setBeanName("channel");
131137
IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(producer);
132138

133139
BridgeHandler bridgeHandler = new BridgeHandler();
140+
bridgeHandler.setBeanName("bridge");
134141

135142
IntegrationFlow flow =
136143
flowBuilder.handle(bridgeHandler)
@@ -145,9 +152,15 @@ protected void doStart() {
145152

146153
assertTrue(replyProducers.contains(bridgeHandler));
147154

155+
assertNotNull(this.integrationManagementConfigurer.getChannelMetrics("channel"));
156+
assertNotNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge"));
157+
148158
flowRegistration.destroy();
149159

150160
assertFalse(replyProducers.contains(bridgeHandler));
161+
162+
assertNull(this.integrationManagementConfigurer.getChannelMetrics("channel"));
163+
assertNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge"));
151164
}
152165

153166
@Test
@@ -504,6 +517,7 @@ public void testConcurrentRegistration() throws InterruptedException {
504517
@Configuration
505518
@EnableIntegration
506519
@EnableMessageHistory
520+
@EnableIntegrationManagement
507521
public static class RootConfiguration {
508522

509523
@Bean

spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import org.springframework.integration.IntegrationMessageHeaderAccessor;
4747
import org.springframework.integration.channel.QueueChannel;
4848
import org.springframework.integration.config.EnableIntegration;
49+
import org.springframework.integration.config.EnableIntegrationManagement;
50+
import org.springframework.integration.config.IntegrationManagementConfigurer;
4951
import org.springframework.integration.core.MessageSource;
5052
import org.springframework.integration.dsl.IntegrationFlow;
5153
import org.springframework.integration.dsl.IntegrationFlows;
@@ -85,6 +87,9 @@ public class FtpTests extends FtpTestSupport {
8587
@Autowired
8688
private ApplicationContext context;
8789

90+
@Autowired
91+
private IntegrationManagementConfigurer integrationManagementConfigurer;
92+
8893
@Test
8994
public void testFtpInboundFlow() throws IOException {
9095
QueueChannel out = new QueueChannel();
@@ -132,7 +137,12 @@ public void testFtpInboundFlow() throws IOException {
132137

133138
MessageSource<?> source = context.getBean(FtpInboundFileSynchronizingMessageSource.class);
134139
assertThat(TestUtils.getPropertyValue(source, "maxFetchSize"), equalTo(10));
140+
141+
assertNotNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source"));
142+
135143
registration.destroy();
144+
145+
assertNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source"));
136146
}
137147

138148
@Test
@@ -221,6 +231,7 @@ public void testFtpMgetFlow() {
221231

222232
@Configuration
223233
@EnableIntegration
234+
@EnableIntegrationManagement
224235
public static class ContextConfiguration {
225236

226237
}

0 commit comments

Comments
 (0)