From a2f2df0b17ed2f5483bce614dc751483708ed17d Mon Sep 17 00:00:00 2001 From: Michael Minella Date: Mon, 22 Sep 2014 13:45:43 -0500 Subject: [PATCH] Conditionally add custom scopes when using XML configuration When using a combination of Java configuration and the XML namespace configuration, prior to this commit, we would add the batch custom scopes twice which lead to issues. This commit gives priority to the custom scopes provided by the java configuration. If you've used @EnableBatchProcessing and have configured batch components using the batch namespace, the custom scopes that come with the java config will take precidence. This commit addresses Jira BATCH-2266 --- .../AbstractBatchConfiguration.java | 9 ++-- .../configuration/xml/CoreNamespaceUtils.java | 15 ++++--- .../StepScopeConfigurationTests.java | 45 +++++++++++++++++-- ...onTestsXmlImportUsingNamespace-context.xml | 18 ++++++++ 4 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTestsXmlImportUsingNamespace-context.xml diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java index bd51bef4f..1997a0f98 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java @@ -20,8 +20,9 @@ import org.springframework.batch.core.configuration.support.MapJobRegistry; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.scope.JobScope; +import org.springframework.batch.core.scope.StepScope; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -30,8 +31,6 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.Assert; -import org.springframework.batch.core.scope.JobScope; -import org.springframework.batch.core.scope.StepScope; import javax.sql.DataSource; import java.util.Collection; @@ -41,6 +40,7 @@ import java.util.Collection; * available by implementing the {@link BatchConfigurer} interface. {@link BatchConfigurer}. * * @author Dave Syer + * @author Michael Minella * @since 2.2 * @see EnableBatchProcessing */ @@ -48,9 +48,6 @@ import java.util.Collection; @Import(ScopeConfiguration.class) public abstract class AbstractBatchConfiguration implements ImportAware { - @Autowired - private ApplicationContext context; - @Autowired(required = false) private Collection dataSources; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceUtils.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceUtils.java index 1f19b6f56..7492990e7 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceUtils.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceUtils.java @@ -15,9 +15,6 @@ */ package org.springframework.batch.core.configuration.xml; -import java.util.Comparator; -import java.util.Map; - import org.springframework.batch.core.job.flow.support.DefaultStateTransitionComparator; import org.springframework.batch.core.job.flow.support.StateTransition; import org.springframework.beans.PropertyValue; @@ -31,6 +28,9 @@ import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; import org.w3c.dom.Element; +import java.util.Comparator; +import java.util.Map; + /** * Utility methods used in parsing of the batch core namespace * @@ -41,7 +41,9 @@ public class CoreNamespaceUtils { private static final String STEP_SCOPE_PROCESSOR_BEAN_NAME = "org.springframework.batch.core.scope.internalStepScope"; - private static final String STEP_SCOPE_PROCESSOR_CLASS_NAME = "org.springframework.batch.core.scope.StepScope"; + private static final String XML_CONFIG_STEP_SCOPE_PROCESSOR_CLASS_NAME = "org.springframework.batch.core.scope.StepScope"; + + private static final String JAVA_CONFIG_SCOPE_CLASS_NAME = "org.springframework.batch.core.configuration.annotation.ScopeConfiguration"; private static final String JOB_SCOPE_PROCESSOR_BEAN_NAME = "org.springframework.batch.core.scope.internalJobScope"; @@ -56,6 +58,7 @@ public class CoreNamespaceUtils { private static final String CORE_NAMESPACE_POST_PROCESSOR_CLASS_NAME = "org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor"; public static void autoregisterBeansForNamespace(ParserContext parserContext, Object source) { + System.out.println("******** CoreNamespaceUtils is called"); checkForStepScope(parserContext, source); checkForJobScope(parserContext, source); addRangePropertyEditor(parserContext); @@ -64,7 +67,7 @@ public class CoreNamespaceUtils { } private static void checkForStepScope(ParserContext parserContext, Object source) { - checkForScope(parserContext, source, STEP_SCOPE_PROCESSOR_CLASS_NAME, STEP_SCOPE_PROCESSOR_BEAN_NAME); + checkForScope(parserContext, source, XML_CONFIG_STEP_SCOPE_PROCESSOR_CLASS_NAME, STEP_SCOPE_PROCESSOR_BEAN_NAME); } private static void checkForJobScope(ParserContext parserContext, Object source) { @@ -77,7 +80,7 @@ public class CoreNamespaceUtils { String[] beanNames = parserContext.getRegistry().getBeanDefinitionNames(); for (String beanName : beanNames) { BeanDefinition bd = parserContext.getRegistry().getBeanDefinition(beanName); - if (scopeClassName.equals(bd.getBeanClassName())) { + if (scopeClassName.equals(bd.getBeanClassName()) || JAVA_CONFIG_SCOPE_CLASS_NAME.equals(bd.getBeanClassName())) { foundScope = true; break; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTests.java index 95e244dba..5ccb32567 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTests.java @@ -16,29 +16,35 @@ package org.springframework.batch.core.configuration.annotation; -import static org.junit.Assert.assertEquals; - -import java.util.concurrent.Callable; - import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.scope.context.StepSynchronizationManager; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.repeat.RepeatStatus; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.context.support.ClassPathXmlApplicationContext; +import java.util.concurrent.Callable; + +import static org.junit.Assert.assertEquals; + /** * @author Dave Syer + * @author Michael Minella * */ public class StepScopeConfigurationTests { @@ -85,6 +91,16 @@ public class StepScopeConfigurationTests { assertEquals("STEP", value.call()); } + @Test + public void testStepScopeXmlImportUsingNamespace() throws Exception { + init(StepScopeConfigurationXmlImportUsingNamespace.class); + + SimpleHolder value = (SimpleHolder) context.getBean("xmlValue"); + assertEquals("STEP", value.call()); + value = (SimpleHolder) context.getBean("javaValue"); + assertEquals("STEP", value.call()); + } + @Test public void testStepScopeWithProxyTargetClassInjected() throws Exception { init(StepScopeConfigurationInjectingProxy.class); @@ -199,6 +215,20 @@ public class StepScopeConfigurationTests { } + @Configuration + @ImportResource("org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTestsXmlImportUsingNamespace-context.xml") + @EnableBatchProcessing + public static class StepScopeConfigurationXmlImportUsingNamespace { + + @Bean + @StepScope + protected SimpleHolder javaValue(@Value("#{stepExecution.stepName}") + final String value) { + return new SimpleHolder(value); + } + + } + @Configuration @EnableBatchProcessing public static class StepScopeConfigurationInjectingProxy { @@ -256,4 +286,11 @@ public class StepScopeConfigurationTests { } + public static class TaskletSupport implements Tasklet { + + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + return RepeatStatus.FINISHED; + } + } } diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTestsXmlImportUsingNamespace-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTestsXmlImportUsingNamespace-context.xml new file mode 100644 index 000000000..edf970547 --- /dev/null +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/annotation/StepScopeConfigurationTestsXmlImportUsingNamespace-context.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file