Fix DisposableBean omission for Java DSL

http://stackoverflow.com/questions/43193858/tomcat-hangs-shutting-down-with-spring-integration-java-dsl

Using manual singleton registration doesn't provide automatic
`DisposableBean` registration

* Improve `IntegrationFlowBeanPostProcessor` to register `DisposableBean`  as well
* Improve `IntegrationFlowContext` to register `DisposableBean`  as well
This commit is contained in:
Artem Bilan
2017-04-03 19:09:39 -04:00
committed by Gary Russell
parent 80d22cb46d
commit 8902fb9489
3 changed files with 27 additions and 3 deletions

View File

@@ -27,11 +27,13 @@ import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
@@ -283,6 +285,11 @@ public class IntegrationFlowBeanPostProcessor implements BeanPostProcessor, Bean
this.beanFactory.registerDependentBean(parentName, beanName);
}
}
if (component instanceof DisposableBean) {
((DefaultSingletonBeanRegistry) this.beanFactory)
.registerDisposableBean(beanName, (DisposableBean) component);
}
}
private String generateBeanName(Object instance) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2017 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.
@@ -23,6 +23,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
@@ -122,6 +123,10 @@ public final class IntegrationFlowContext implements BeanFactoryAware {
if (parentName != null) {
this.beanFactory.registerDependentBean(parentName, beanName);
}
if (bean instanceof DisposableBean) {
((DefaultSingletonBeanRegistry) this.beanFactory)
.registerDisposableBean(beanName, (DisposableBean) bean);
}
return bean;
}
@@ -186,7 +191,7 @@ public final class IntegrationFlowContext implements BeanFactoryAware {
*/
public final class IntegrationFlowRegistrationBuilder {
private Map<Object, String> additionalBeans = new HashMap<Object, String>();
private Map<Object, String> additionalBeans = new HashMap<>();
private final IntegrationFlowRegistration integrationFlowRegistration;

View File

@@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Date;
@@ -34,6 +35,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -127,6 +129,8 @@ public class ManualFlowTests {
ThreadPoolTaskScheduler taskScheduler = this.beanFactory.getBean(ThreadPoolTaskScheduler.class);
Thread.sleep(100);
assertEquals(0, taskScheduler.getActiveCount());
assertTrue(additionalBean.destroyed);
}
@Test
@@ -288,11 +292,14 @@ public class ManualFlowTests {
}
private final class BeanFactoryHandler extends AbstractReplyProducingMessageHandler {
private final class BeanFactoryHandler extends AbstractReplyProducingMessageHandler
implements DisposableBean {
@Autowired
private BeanFactory beanFactory;
private boolean destroyed;
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
Objects.requireNonNull(this.beanFactory);
@@ -304,6 +311,11 @@ public class ManualFlowTests {
this.beanFactory.getClass(); // ensure wiring before afterPropertiesSet()
}
@Override
public void destroy() throws Exception {
this.destroyed = true;
}
}
}