BATCH-1775: fix inner bean definition parser inside <chunk/> element

This commit is contained in:
Dave Syer
2011-07-27 09:32:24 +01:00
parent 93ade2b5f6
commit c321a1dc07
3 changed files with 95 additions and 13 deletions

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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>