diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java index eede88513c..640d6d136c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java @@ -27,7 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.SmartInitializingSingleton; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.integration.core.MessageSource; @@ -64,8 +64,9 @@ import org.springframework.util.StringUtils; * @since 4.2 * */ -public class IntegrationManagementConfigurer implements SmartInitializingSingleton, ApplicationContextAware, - BeanNameAware, BeanPostProcessor { +public class IntegrationManagementConfigurer + implements SmartInitializingSingleton, ApplicationContextAware, BeanNameAware, + DestructionAwareBeanPostProcessor { private static final Log logger = LogFactory.getLog(IntegrationManagementConfigurer.class); @@ -246,7 +247,8 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet this.metricsFactory = new DefaultMetricsFactory(); } this.sourceConfigurers.putAll(this.applicationContext.getBeansOfType(MessageSourceMetricsConfigurer.class)); - Map managed = this.applicationContext.getBeansOfType(IntegrationManagement.class); + Map managed = this.applicationContext + .getBeansOfType(IntegrationManagement.class); for (Entry entry : managed.entrySet()) { IntegrationManagement bean = entry.getValue(); if (!bean.getOverrides().loggingConfigured) { @@ -259,7 +261,8 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet } private void injectCaptor() { - Map managed = this.applicationContext.getBeansOfType(IntegrationManagement.class); + Map managed = this.applicationContext + .getBeansOfType(IntegrationManagement.class); for (Entry entry : managed.entrySet()) { IntegrationManagement bean = entry.getValue(); if (!bean.getOverrides().loggingConfigured) { @@ -280,6 +283,30 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet return bean; } + @Override + public boolean requiresDestruction(Object bean) { + return bean instanceof MessageChannelMetrics || + bean instanceof MessageHandlerMetrics || + bean instanceof MessageSourceMetrics; + } + + @Override + public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { + if (bean instanceof MessageChannelMetrics) { + this.channelsByName.remove(beanName); + } + else if (bean instanceof MessageHandlerMetrics) { + if (this.handlersByName.remove(beanName) == null) { + this.handlersByName.remove(beanName + ".handler"); + } + } + else if (bean instanceof MessageSourceMetrics) { + if (this.sourcesByName.remove(beanName) == null) { + this.sourcesByName.remove(beanName + ".source"); + } + } + } + private Object doConfigureMetrics(Object bean, String name) { if (bean instanceof MessageChannelMetrics) { configureChannelMetrics(name, (MessageChannelMetrics) bean); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java b/spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java index 24ea3e53cb..2389fd6afb 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java @@ -60,7 +60,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.config.EnableIntegrationManagement; import org.springframework.integration.config.EnableMessageHistory; +import org.springframework.integration.config.IntegrationManagementConfigurer; import org.springframework.integration.core.MessageProducer; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.dsl.IntegrationFlow; @@ -114,6 +116,9 @@ public class ManualFlowTests { @Autowired private SmartLifecycleRoleController roleController; + @Autowired + private IntegrationManagementConfigurer integrationManagementConfigurer; + @Test @SuppressWarnings("unchecked") public void testWithAnonymousMessageProducerStart() { @@ -128,9 +133,11 @@ public class ManualFlowTests { }; QueueChannel channel = new QueueChannel(); + channel.setBeanName("channel"); IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(producer); BridgeHandler bridgeHandler = new BridgeHandler(); + bridgeHandler.setBeanName("bridge"); IntegrationFlow flow = flowBuilder.handle(bridgeHandler) @@ -145,9 +152,15 @@ public class ManualFlowTests { assertTrue(replyProducers.contains(bridgeHandler)); + assertNotNull(this.integrationManagementConfigurer.getChannelMetrics("channel")); + assertNotNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge")); + flowRegistration.destroy(); assertFalse(replyProducers.contains(bridgeHandler)); + + assertNull(this.integrationManagementConfigurer.getChannelMetrics("channel")); + assertNull(this.integrationManagementConfigurer.getHandlerMetrics("bridge")); } @Test @@ -504,6 +517,7 @@ public class ManualFlowTests { @Configuration @EnableIntegration @EnableMessageHistory + @EnableIntegrationManagement public static class RootConfiguration { @Bean diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java index 63357b3a0f..6018c4cecc 100644 --- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java +++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java @@ -46,6 +46,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.integration.IntegrationMessageHeaderAccessor; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.config.EnableIntegrationManagement; +import org.springframework.integration.config.IntegrationManagementConfigurer; import org.springframework.integration.core.MessageSource; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.IntegrationFlows; @@ -85,6 +87,9 @@ public class FtpTests extends FtpTestSupport { @Autowired private ApplicationContext context; + @Autowired + private IntegrationManagementConfigurer integrationManagementConfigurer; + @Test public void testFtpInboundFlow() throws IOException { QueueChannel out = new QueueChannel(); @@ -132,7 +137,12 @@ public class FtpTests extends FtpTestSupport { MessageSource source = context.getBean(FtpInboundFileSynchronizingMessageSource.class); assertThat(TestUtils.getPropertyValue(source, "maxFetchSize"), equalTo(10)); + + assertNotNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source")); + registration.destroy(); + + assertNull(this.integrationManagementConfigurer.getSourceMetrics("ftpInboundAdapter.source")); } @Test @@ -221,6 +231,7 @@ public class FtpTests extends FtpTestSupport { @Configuration @EnableIntegration + @EnableIntegrationManagement public static class ContextConfiguration { }