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
This commit is contained in:
@@ -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<DataSource> dataSources;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
|
||||
|
||||
<bean id="tasklet" class="org.springframework.batch.core.configuration.annotation.StepScopeConfigurationTests$TaskletSupport"/>
|
||||
|
||||
<job id="job" xmlns="http://www.springframework.org/schema/batch">
|
||||
<step id="step1">
|
||||
<tasklet ref="tasklet"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<bean id="xmlValue" class="org.springframework.batch.core.configuration.annotation.StepScopeConfigurationTests.SimpleHolder" scope="step">
|
||||
<constructor-arg value="#{stepExecution.stepName}" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user