diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessor.java index c8ee98bdfd..b23c6e0b88 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessor.java @@ -54,8 +54,12 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; this.registerNullChannel(registry); - this.registerErrorChannelIfNecessary(registry); - this.registerTaskSchedulerIfNecessary(registry); + if (!beanFactory.containsBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) { + this.registerErrorChannel(registry); + } + if (!beanFactory.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) { + this.registerTaskScheduler(registry); + } this.registerIdGeneratorConfigurer(registry); } else if (logger.isWarnEnabled()) { @@ -89,9 +93,9 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce * {@link IntegrationContextUtils#NULL_CHANNEL_BEAN_NAME}. */ private void registerNullChannel(BeanDefinitionRegistry registry) { - if (registry.isBeanNameInUse(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)) { - BeanDefinition bDef = registry.getBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME); - if (bDef.getBeanClassName().equals(NullChannel.class.getName())) { + if (registry.containsBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)) { + BeanDefinition nullChannelDefinition = registry.getBeanDefinition(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME); + if (NullChannel.class.getName().equals(nullChannelDefinition.getBeanClassName())) { return; } else { @@ -109,63 +113,51 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce } /** - * Register an error channel in the given BeanDefinitionRegistry if not yet present. The bean name for which this is - * checking is defined by the constant {@link IntegrationContextUtils#ERROR_CHANNEL_BEAN_NAME}. + * Register an error channel in the given BeanDefinitionRegistry. */ - private void registerErrorChannelIfNecessary(BeanDefinitionRegistry registry) { - if (!registry.isBeanNameInUse(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) { - if (logger.isInfoEnabled()) { - logger - .info("No bean named '" - + IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME - + "' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created."); - } - RootBeanDefinition errorChannelDef = new RootBeanDefinition(); - errorChannelDef.setBeanClassName(IntegrationNamespaceUtils.BASE_PACKAGE - + ".channel.PublishSubscribeChannel"); - BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(errorChannelDef, - IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); - BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry); - BeanDefinitionBuilder loggingHandlerBuilder = BeanDefinitionBuilder - .genericBeanDefinition(IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.LoggingHandler"); - loggingHandlerBuilder.addConstructorArgValue("ERROR"); - BeanDefinitionBuilder loggingEndpointBuilder = BeanDefinitionBuilder - .genericBeanDefinition(IntegrationNamespaceUtils.BASE_PACKAGE + ".endpoint.EventDrivenConsumer"); - loggingEndpointBuilder.addConstructorArgReference(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); - loggingEndpointBuilder.addConstructorArgValue(loggingHandlerBuilder.getBeanDefinition()); - BeanComponentDefinition componentDefinition = new BeanComponentDefinition(loggingEndpointBuilder - .getBeanDefinition(), ERROR_LOGGER_BEAN_NAME); - BeanDefinitionReaderUtils.registerBeanDefinition(componentDefinition, registry); + private void registerErrorChannel(BeanDefinitionRegistry registry) { + if (logger.isInfoEnabled()) { + logger.info("No bean named '" + IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME + + "' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created."); } + RootBeanDefinition errorChannelDef = new RootBeanDefinition(); + errorChannelDef.setBeanClassName(IntegrationNamespaceUtils.BASE_PACKAGE + + ".channel.PublishSubscribeChannel"); + BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(errorChannelDef, + IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); + BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry); + BeanDefinitionBuilder loggingHandlerBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.LoggingHandler"); + loggingHandlerBuilder.addConstructorArgValue("ERROR"); + BeanDefinitionBuilder loggingEndpointBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".endpoint.EventDrivenConsumer"); + loggingEndpointBuilder.addConstructorArgReference(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); + loggingEndpointBuilder.addConstructorArgValue(loggingHandlerBuilder.getBeanDefinition()); + BeanComponentDefinition componentDefinition = new BeanComponentDefinition( + loggingEndpointBuilder.getBeanDefinition(), ERROR_LOGGER_BEAN_NAME); + BeanDefinitionReaderUtils.registerBeanDefinition(componentDefinition, registry); } /** - * Register a TaskScheduler in the given BeanDefinitionRegistry if not yet present. The bean name for which this is - * checking is defined by the constant {@link IntegrationContextUtils#TASK_SCHEDULER_BEAN_NAME}. + * Register a TaskScheduler in the given BeanDefinitionRegistry. */ - private void registerTaskSchedulerIfNecessary(BeanDefinitionRegistry registry) { - if (!registry.isBeanNameInUse(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) { - if (logger.isInfoEnabled()) { - logger - .info("No bean named '" - + IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME - + "' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created."); - } - BeanDefinitionBuilder schedulerBuilder = BeanDefinitionBuilder - .genericBeanDefinition("org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"); - schedulerBuilder.addPropertyValue("poolSize", 10); - schedulerBuilder.addPropertyValue("threadNamePrefix", "task-scheduler-"); - schedulerBuilder.addPropertyValue("rejectedExecutionHandler", new CallerRunsPolicy()); - BeanDefinitionBuilder errorHandlerBuilder = BeanDefinitionBuilder - .genericBeanDefinition(IntegrationNamespaceUtils.BASE_PACKAGE - + ".channel.MessagePublishingErrorHandler"); - errorHandlerBuilder.addPropertyReference("defaultErrorChannel", - IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); - schedulerBuilder.addPropertyValue("errorHandler", errorHandlerBuilder.getBeanDefinition()); - BeanComponentDefinition schedulerComponent = new BeanComponentDefinition(schedulerBuilder - .getBeanDefinition(), IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME); - BeanDefinitionReaderUtils.registerBeanDefinition(schedulerComponent, registry); + private void registerTaskScheduler(BeanDefinitionRegistry registry) { + if (logger.isInfoEnabled()) { + logger.info("No bean named '" + IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME + + "' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created."); } + BeanDefinitionBuilder schedulerBuilder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"); + schedulerBuilder.addPropertyValue("poolSize", 10); + schedulerBuilder.addPropertyValue("threadNamePrefix", "task-scheduler-"); + schedulerBuilder.addPropertyValue("rejectedExecutionHandler", new CallerRunsPolicy()); + BeanDefinitionBuilder errorHandlerBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".channel.MessagePublishingErrorHandler"); + errorHandlerBuilder.addPropertyReference("defaultErrorChannel", IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); + schedulerBuilder.addPropertyValue("errorHandler", errorHandlerBuilder.getBeanDefinition()); + BeanComponentDefinition schedulerComponent = new BeanComponentDefinition( + schedulerBuilder.getBeanDefinition(), IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME); + BeanDefinitionReaderUtils.registerBeanDefinition(schedulerComponent, registry); } } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessorTests.java index 764d5f0f0b..74d1ebd7cf 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/DefaultConfiguringBeanFactoryPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2011 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,25 +16,29 @@ package org.springframework.integration.config.xml; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; - import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.channel.MessagePublishingErrorHandler; import org.springframework.integration.channel.NullChannel; import org.springframework.integration.channel.PublishSubscribeChannel; import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + /** * @author Mark Fisher + * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @@ -67,5 +71,21 @@ public class DefaultConfiguringBeanFactoryPostProcessorTests { Object defaultErrorChannel = new DirectFieldAccessor(errorHandler).getPropertyValue("defaultErrorChannel"); assertEquals(context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME), defaultErrorChannel); } + + @Test + public void taskSchedulerNotRegisteredMoreThanOnce() { + ClassPathXmlApplicationContext superParentApplicationContext = new ClassPathXmlApplicationContext("superParentApplicationContext.xml", this.getClass()); + ClassPathXmlApplicationContext parentApplicationContext = + new ClassPathXmlApplicationContext(new String[]{"org/springframework/integration/config/xml/parentApplicationContext.xml"}, superParentApplicationContext); + ClassPathXmlApplicationContext childApplicationContext = + new ClassPathXmlApplicationContext(new String[]{"org/springframework/integration/config/xml/childApplicationContext.xml"}, parentApplicationContext); + System.out.println(Arrays.asList(childApplicationContext.getBeanDefinitionNames())); + TaskScheduler parentScheduler = childApplicationContext.getParent().getBean("taskScheduler", TaskScheduler.class); + TaskScheduler childScheduler = childApplicationContext.getBean("taskScheduler", TaskScheduler.class); + + assertNotNull("Child task scheduler was null", childScheduler); + assertNotNull("Parent task scheduler was null", parentScheduler); + assertEquals("Different schedulers in parent and child", parentScheduler, childScheduler ); + } } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/childApplicationContext.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/childApplicationContext.xml new file mode 100644 index 0000000000..0078147aa2 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/childApplicationContext.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/parentApplicationContext.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/parentApplicationContext.xml new file mode 100644 index 0000000000..2c31c66eb8 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/parentApplicationContext.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/superParentApplicationContext.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/superParentApplicationContext.xml new file mode 100644 index 0000000000..7fb0e656e9 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/superParentApplicationContext.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file