BATCH-1775: fix inner bean definition parser inside <chunk/> element
This commit is contained in:
@@ -75,11 +75,11 @@ public class ChunkElementParser {
|
||||
|
||||
propertyValues.addPropertyValue("hasChunkElement", Boolean.TRUE);
|
||||
|
||||
handleItemHandler("reader", "itemReader", ITEM_READER_ADAPTER_CLASS, true, element, parserContext,
|
||||
handleItemHandler(bd, "reader", "itemReader", ITEM_READER_ADAPTER_CLASS, true, element, parserContext,
|
||||
propertyValues, underspecified);
|
||||
handleItemHandler("processor", "itemProcessor", ITEM_PROCESSOR_ADAPTER_CLASS, false, element, parserContext,
|
||||
handleItemHandler(bd, "processor", "itemProcessor", ITEM_PROCESSOR_ADAPTER_CLASS, false, element, parserContext,
|
||||
propertyValues, underspecified);
|
||||
handleItemHandler("writer", "itemWriter", ITEM_WRITER_ADAPTER_CLASS, true, element, parserContext,
|
||||
handleItemHandler(bd, "writer", "itemWriter", ITEM_WRITER_ADAPTER_CLASS, true, element, parserContext,
|
||||
propertyValues, underspecified);
|
||||
|
||||
String commitInterval = element.getAttribute(COMMIT_INTERVAL_ATTR);
|
||||
@@ -131,7 +131,7 @@ public class ChunkElementParser {
|
||||
// classes for an abstract parent bean definition
|
||||
propertyValues.addPropertyValue("skippableExceptionClasses", skippableExceptions);
|
||||
|
||||
handleItemHandler("skip-policy", "skipPolicy", null, false, element, parserContext, propertyValues,
|
||||
handleItemHandler(bd, "skip-policy", "skipPolicy", null, false, element, parserContext, propertyValues,
|
||||
underspecified);
|
||||
|
||||
String retryLimit = element.getAttribute("retry-limit");
|
||||
@@ -147,7 +147,7 @@ public class ChunkElementParser {
|
||||
// classes for an abstract parent bean definition
|
||||
propertyValues.addPropertyValue("retryableExceptionClasses", retryableExceptions);
|
||||
|
||||
handleItemHandler("retry-policy", "retryPolicy", null, false, element, parserContext, propertyValues,
|
||||
handleItemHandler(bd, "retry-policy", "retryPolicy", null, false, element, parserContext, propertyValues,
|
||||
underspecified);
|
||||
|
||||
String cacheCapacity = element.getAttribute("cache-capacity");
|
||||
@@ -176,7 +176,7 @@ public class ChunkElementParser {
|
||||
/**
|
||||
* Handle the ItemReader, ItemProcessor, and ItemWriter attributes/elements.
|
||||
*/
|
||||
private void handleItemHandler(String handlerName, String propertyName, String adapterClassName, boolean required,
|
||||
private void handleItemHandler(AbstractBeanDefinition enclosing, String handlerName, String propertyName, String adapterClassName, boolean required,
|
||||
Element element, ParserContext parserContext, MutablePropertyValues propertyValues, boolean underspecified) {
|
||||
String refName = element.getAttribute(handlerName);
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -187,7 +187,7 @@ public class ChunkElementParser {
|
||||
"The <" + element.getNodeName() + "/> element may not have both a '" + handlerName
|
||||
+ "' attribute and a <" + handlerName + "/> element.", element);
|
||||
}
|
||||
handleItemHandlerElement(propertyName, adapterClassName, propertyValues, children.get(0), parserContext);
|
||||
handleItemHandlerElement(enclosing, propertyName, adapterClassName, propertyValues, children.get(0), parserContext);
|
||||
}
|
||||
else if (children.size() > 1) {
|
||||
parserContext.getReaderContext().error(
|
||||
@@ -209,7 +209,7 @@ public class ChunkElementParser {
|
||||
* is defined within the item handler.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleItemHandlerElement(String propertyName, String adapterClassName,
|
||||
private void handleItemHandlerElement(AbstractBeanDefinition enclosing, String propertyName, String adapterClassName,
|
||||
MutablePropertyValues propertyValues, Element element, ParserContext parserContext) {
|
||||
List<Element> beanElements = DomUtils.getChildElementsByTagName(element, BEAN_ELE);
|
||||
List<Element> refElements = DomUtils.getChildElementsByTagName(element, REF_ELE);
|
||||
@@ -221,8 +221,9 @@ public class ChunkElementParser {
|
||||
else if (beanElements.size() == 1) {
|
||||
Element beanElement = beanElements.get(0);
|
||||
BeanDefinitionHolder beanDefinitionHolder = parserContext.getDelegate().parseBeanDefinitionElement(
|
||||
beanElement);
|
||||
beanElement, enclosing);
|
||||
parserContext.getDelegate().decorateBeanDefinitionIfRequired(beanElement, beanDefinitionHolder);
|
||||
|
||||
propertyValues.addPropertyValue(propertyName, beanDefinitionHolder);
|
||||
}
|
||||
else if (refElements.size() == 1) {
|
||||
|
||||
@@ -3,7 +3,14 @@ package org.springframework.batch.core.configuration.xml;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.scope.context.StepSynchronizationManager;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.adapter.ItemProcessorAdapter;
|
||||
import org.springframework.batch.item.adapter.ItemReaderAdapter;
|
||||
import org.springframework.batch.item.adapter.ItemWriterAdapter;
|
||||
@@ -17,12 +24,21 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
*/
|
||||
public class InlineItemHandlerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/batch/core/configuration/xml/InlineItemHandlerParserTests-context.xml");
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
StepSynchronizationManager.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInlineHandlers() throws Exception {
|
||||
Object step = ctx.getBean("inlineHandlers");
|
||||
context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/batch/core/configuration/xml/InlineItemHandlerParserTests-context.xml");
|
||||
Object step = context.getBean("inlineHandlers");
|
||||
Object tasklet = ReflectionTestUtils.getField(step, "tasklet");
|
||||
Object chunkProvider = ReflectionTestUtils.getField(tasklet, "chunkProvider");
|
||||
Object reader = ReflectionTestUtils.getField(chunkProvider, "itemReader");
|
||||
@@ -37,7 +53,9 @@ public class InlineItemHandlerParserTests {
|
||||
|
||||
@Test
|
||||
public void testInlineAdapters() throws Exception {
|
||||
Object step = ctx.getBean("inlineAdapters");
|
||||
context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/batch/core/configuration/xml/InlineItemHandlerParserTests-context.xml");
|
||||
Object step = context.getBean("inlineAdapters");
|
||||
Object tasklet = ReflectionTestUtils.getField(step, "tasklet");
|
||||
Object chunkProvider = ReflectionTestUtils.getField(tasklet, "chunkProvider");
|
||||
Object reader = ReflectionTestUtils.getField(chunkProvider, "itemReader");
|
||||
@@ -64,4 +82,17 @@ public class InlineItemHandlerParserTests {
|
||||
assertEquals("dummyWrite", writerMethod);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInlineHandlersWithStepScope() throws Exception {
|
||||
context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/batch/core/configuration/xml/InlineItemHandlerWithStepScopeParserTests-context.xml");
|
||||
StepSynchronizationManager.register(new StepExecution("step", new JobExecution(123L)));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,ItemReader<?>> readers = context.getBeansOfType(ItemReader.class);
|
||||
// Should be 2 each (proxy and target) for the two readers in the steps defined
|
||||
assertEquals(4, readers.size());
|
||||
// System.err.println(readers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<beans:bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
|
||||
|
||||
<beans:bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
|
||||
<beans:property name="transactionManager" ref="transactionManager" />
|
||||
</beans:bean>
|
||||
|
||||
|
||||
<step id="inlineHandlers">
|
||||
<tasklet>
|
||||
<chunk commit-interval="5">
|
||||
<reader>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestReader" scope="step"/>
|
||||
</reader>
|
||||
|
||||
<processor>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestProcessor" scope="step"/>
|
||||
</processor>
|
||||
|
||||
<writer>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestWriter" scope="step"/>
|
||||
</writer>
|
||||
</chunk>
|
||||
</tasklet>
|
||||
</step>
|
||||
|
||||
<step id="moreInlineHandlers">
|
||||
<tasklet>
|
||||
<chunk commit-interval="5">
|
||||
<reader>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestReader" scope="step"/>
|
||||
</reader>
|
||||
|
||||
<processor>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestProcessor" scope="step"/>
|
||||
</processor>
|
||||
|
||||
<writer>
|
||||
<beans:bean class="org.springframework.batch.core.configuration.xml.TestWriter" scope="step"/>
|
||||
</writer>
|
||||
</chunk>
|
||||
</tasklet>
|
||||
</step>
|
||||
|
||||
</beans:beans>
|
||||
Reference in New Issue
Block a user