diff --git a/spring-integration-core/src/main/java/org/springframework/integration/history/MessageHistoryConfigurer.java b/spring-integration-core/src/main/java/org/springframework/integration/history/MessageHistoryConfigurer.java index 3112e886b3..719831f5ef 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/history/MessageHistoryConfigurer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/history/MessageHistoryConfigurer.java @@ -29,7 +29,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionValidationException; import org.springframework.context.SmartLifecycle; import org.springframework.integration.support.management.IntegrationManagedResource; @@ -50,13 +50,13 @@ import org.springframework.util.StringUtils; */ @ManagedResource @IntegrationManagedResource -public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAware, BeanPostProcessor { +public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAware, DestructionAwareBeanPostProcessor { private final Log logger = LogFactory.getLog(this.getClass()); private final Set currentlyTrackedComponents = ConcurrentHashMap.newKeySet(); - private String[] componentNamePatterns = new String[] { "*" }; + private String[] componentNamePatterns = new String[]{ "*" }; private boolean componentNamePatternsExplicitlySet; @@ -98,7 +98,7 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar */ @ManagedAttribute(description = "comma-delimited list of patterns; must invoke stop() before changing.") public void setComponentNamePatternsString(String componentNamePatterns) { - this.setComponentNamePatterns(StringUtils.delimitedListToStringArray(componentNamePatterns, ",", " ")); + setComponentNamePatterns(StringUtils.delimitedListToStringArray(componentNamePatterns, ",", " ")); } @ManagedAttribute @@ -160,6 +160,16 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar } } + @Override + public boolean requiresDestruction(Object bean) { + return bean instanceof TrackableComponent; + } + + @Override + public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { + this.currentlyTrackedComponents.remove(bean); + } + /* * SmartLifecycle implementation */ diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterHelper.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterHelper.java index 6b4518b9ed..2287f6a81c 100644 --- a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterHelper.java +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,17 @@ package org.springframework.integration.jmx.config; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; -import java.util.List; +import java.util.Queue; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.beans.DirectFieldAccessor; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.integration.monitor.IntegrationMBeanExporter; @@ -40,28 +41,29 @@ import org.springframework.jmx.export.MBeanExporter; * * @author Oleg Zhurakousky * @author Artem Bilan + * * @since 2.1 * */ -class MBeanExporterHelper implements BeanPostProcessor, Ordered { +class MBeanExporterHelper implements DestructionAwareBeanPostProcessor, Ordered { - private final List mBeanExportersForExcludes = new ArrayList(); + private final Queue mBeanExportersForExcludes = new ConcurrentLinkedQueue<>(); - private final Set siBeanNames = new HashSet(); + private final Set siBeanNames = ConcurrentHashMap.newKeySet(); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("$autoCreateChannelCandidates".equals(beanName)) { @SuppressWarnings("unchecked") - Collection autoCreateChannelCandidatesNames = (Collection) new DirectFieldAccessor(bean) - .getPropertyValue("channelNames"); + Collection autoCreateChannelCandidatesNames = + (Collection) new DirectFieldAccessor(bean).getPropertyValue("channelNames"); this.siBeanNames.addAll(autoCreateChannelCandidatesNames); if (!this.mBeanExportersForExcludes.isEmpty()) { - for (String autoCreateChannelCandidatesName : autoCreateChannelCandidatesNames) { - for (MBeanExporter mBeanExporter : this.mBeanExportersForExcludes) { - mBeanExporter.addExcludedBean(autoCreateChannelCandidatesName); - } - } + autoCreateChannelCandidatesNames + .stream(). + >map(candidateName -> + mBeanExporter -> mBeanExporter.addExcludedBean(candidateName)) + .forEach(this.mBeanExportersForExcludes::forEach); } } @@ -72,25 +74,37 @@ class MBeanExporterHelper implements BeanPostProcessor, Ordered { public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (AnnotatedElementUtils.isAnnotated(AopUtils.getTargetClass(bean), IntegrationManagedResource.class.getName())) { + this.siBeanNames.add(beanName); - if (!this.mBeanExportersForExcludes.isEmpty()) { - for (MBeanExporter mBeanExporter : this.mBeanExportersForExcludes) { - mBeanExporter.addExcludedBean(beanName); - } - } + this.mBeanExportersForExcludes.forEach(mBeanExporter -> mBeanExporter.addExcludedBean(beanName)); } if (bean instanceof MBeanExporter && !(bean instanceof IntegrationMBeanExporter)) { MBeanExporter mBeanExporter = (MBeanExporter) bean; this.mBeanExportersForExcludes.add(mBeanExporter); - for (String siBeanName : this.siBeanNames) { - mBeanExporter.addExcludedBean(siBeanName); - } + this.siBeanNames.forEach(mBeanExporter::addExcludedBean); } return bean; } + @Override + public boolean requiresDestruction(Object bean) { + return (bean instanceof MBeanExporter && !(bean instanceof IntegrationMBeanExporter)) || + AnnotatedElementUtils.isAnnotated(AopUtils.getTargetClass(bean), + IntegrationManagedResource.class.getName()); + } + + @Override + public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { + if (bean instanceof MBeanExporter) { + this.mBeanExportersForExcludes.remove(bean); + } + else { + this.siBeanNames.remove(beanName); + } + } + @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE;