diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java index 13a3cafffe2..a8b8597cc3f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java @@ -32,6 +32,8 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -83,6 +85,7 @@ * @author Oleg Zhurakousky * @author Artem Bilan * @author Gary Russell + * @author Michael Wiles * * @see IntegrationContextUtils */ @@ -172,18 +175,20 @@ private void registerMessagePublishingErrorHandler() { private void registerNullChannel() { if (this.beanFactory.containsBean(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)) { BeanDefinition nullChannelDefinition = null; - if (this.beanFactory.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)) { - nullChannelDefinition = - this.beanFactory.getBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME); - } - else { - BeanDefinitionRegistry parentBeanFactory = - (BeanDefinitionRegistry) this.beanFactory.getParentBeanFactory(); - if (parentBeanFactory != null) { - nullChannelDefinition = - parentBeanFactory.getBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME); + BeanFactory beanFactory = this.beanFactory; + do { + if (beanFactory instanceof ConfigurableListableBeanFactory) { + ConfigurableListableBeanFactory listable = (ConfigurableListableBeanFactory) beanFactory; + if (listable.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)) { + nullChannelDefinition = listable + .getBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME); + } + } + if (beanFactory instanceof HierarchicalBeanFactory) { + beanFactory = ((HierarchicalBeanFactory) beanFactory).getParentBeanFactory(); } } + while (nullChannelDefinition == null); if (nullChannelDefinition != null && !NullChannel.class.getName().equals(nullChannelDefinition.getBeanClassName())) { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java index 8fc89a306cc..0106301577c 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java @@ -90,6 +90,7 @@ import org.springframework.integration.config.GlobalChannelInterceptor; import org.springframework.integration.config.IntegrationConverter; import org.springframework.integration.config.SpelFunctionFactoryBean; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.core.MessageSource; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.endpoint.AbstractEndpoint; @@ -136,6 +137,7 @@ /** * @author Artem Bilan * @author Gary Russell + * @author Michael Wiles * * @since 4.0 */ @@ -470,6 +472,36 @@ public void testMessagingGateway() throws InterruptedException { assertThat(this.asyncAnnotationProcessThread.get()).isNotSameAs(Thread.currentThread()); } + /** + * Just creates an interim context to confirm that the + * DefaultConfiguringBeanFactoryPostProcessor does not fail when there is an extra + * application context in the hierarchy. + */ + @Test + public void testDoubleParentChildAnnotationConfiguration() { + + assertThat(this.context.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)).isTrue(); + + AnnotationConfigApplicationContext parent; + parent = new AnnotationConfigApplicationContext(); + parent.register(ChildConfiguration.class); + parent.setParent(this.context); + parent.refresh(); + + assertThat(parent.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)).isFalse(); + + AnnotationConfigApplicationContext child; + child = new AnnotationConfigApplicationContext(); + child.register(ChildConfiguration.class); + child.setParent(parent); + child.refresh(); + + assertThat(child.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)).isFalse(); + + parent.close(); + child.close(); + } + @Test public void testParentChildAnnotationConfiguration() { AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();