diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java index c0f8c455e..0a9c18fb4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java @@ -229,7 +229,7 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered { BeanDefinitionRegistry registry, boolean proxyTargetClass) { // TODO: (for Batch 2.1) detect presence of Spring 3.0 and use - // ScopedPoxyUtils instead + // ScopedProxyUtils instead // Create the scoped proxy... BeanDefinitionHolder proxyHolder = PlaceholderProxyFactoryBean.createScopedProxy(new BeanDefinitionHolder( diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java index 3cf598541..9c11945fb 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java @@ -104,6 +104,8 @@ public class PlaceholderProxyFactoryBean extends ProxyConfig implements FactoryB // proxy itself is not subject to auto-proxying! Only its target bean // is. pf.addInterface(AopInfrastructureBean.class); + + this.scopedTargetSource.afterPropertiesSet(); this.proxy = pf.getProxy(cbf.getBeanClassLoader()); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java index dba139d81..8af5203d2 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java @@ -31,6 +31,7 @@ import org.springframework.beans.factory.config.BeanDefinitionVisitor; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.core.AttributeAccessor; import org.springframework.core.MethodParameter; import org.springframework.util.Assert; import org.springframework.util.StringValueResolver; @@ -51,7 +52,8 @@ import org.springframework.util.StringValueResolver; * @author Dave Syer * */ -public class PlaceholderTargetSource extends SimpleBeanTargetSource implements InitializingBean { +public class PlaceholderTargetSource extends SimpleBeanTargetSource implements + InitializingBean { /** * Key for placeholders to be replaced from the properties provided. @@ -62,11 +64,14 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I private ContextFactory contextFactory; + private String beanName; + /** * Public setter for the context factory. Used to construct the context root * whenever placeholders are replaced in a bean definition. * - * @param contextFactory the {@link ContextFactory} + * @param contextFactory + * the {@link ContextFactory} */ public void setContextFactory(ContextFactory contextFactory) { this.contextFactory = contextFactory; @@ -78,8 +83,9 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I * @see * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { Assert.notNull(contextFactory, "The ContextFactory must be set."); + beanName = getTargetBeanName() + "#" + contextFactory.getContextId(); } /* @@ -90,57 +96,69 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I @Override public synchronized Object getTarget() throws BeansException { + // Object target; + Object target = getTargetFromContext(); + if (target != null) { + return target; + } + DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) getBeanFactory(); - final TypeConverter typeConverter = listableBeanFactory.getTypeConverter(); + final TypeConverter typeConverter = listableBeanFactory + .getTypeConverter(); - DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(listableBeanFactory); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory( + listableBeanFactory); beanFactory.copyConfigurationFrom(listableBeanFactory); final TypeConverter contextTypeConverter = new TypeConverter() { @SuppressWarnings("unchecked") - public Object convertIfNecessary(Object value, Class requiredType, MethodParameter methodParam) - throws TypeMismatchException { + public Object convertIfNecessary(Object value, Class requiredType, + MethodParameter methodParam) throws TypeMismatchException { Object result = null; if (value instanceof String) { String key = (String) value; - if (key.startsWith(PLACEHOLDER_PREFIX) && key.endsWith(PLACEHOLDER_SUFFIX)) { + if (key.startsWith(PLACEHOLDER_PREFIX) + && key.endsWith(PLACEHOLDER_SUFFIX)) { key = extractKey(key); - result = convertFromContext(key, requiredType, typeConverter); - if (result==null) { + result = convertFromContext(key, requiredType, + typeConverter); + if (result == null) { Object property = getPropertyFromContext(key); - // Give the normal type converter a chance by reversing to a String - if (property!=null) { - property = convertToString(property, typeConverter); - if (property!=null) { + // Give the normal type converter a chance by + // reversing to a String + if (property != null) { + property = convertToString(property, + typeConverter); + if (property != null) { value = property; } } } } - } - else if (requiredType.isAssignableFrom(value.getClass())) { + } else if (requiredType.isAssignableFrom(value.getClass())) { result = value; - } - else if (requiredType.isAssignableFrom(String.class)) { + } else if (requiredType.isAssignableFrom(String.class)) { result = convertToString(value, typeConverter); if (result == null) { - logger.debug("Falling back on toString for conversion of : [" + value.getClass() + "]"); + logger + .debug("Falling back on toString for conversion of : [" + + value.getClass() + "]"); result = value.toString(); } } - return result != null ? result : typeConverter.convertIfNecessary(value, requiredType, methodParam); + return result != null ? result : typeConverter + .convertIfNecessary(value, requiredType, methodParam); } @SuppressWarnings("unchecked") - public Object convertIfNecessary(Object value, Class requiredType) throws TypeMismatchException { + public Object convertIfNecessary(Object value, Class requiredType) + throws TypeMismatchException { return convertIfNecessary(value, requiredType, null); } }; beanFactory.setTypeConverter(contextTypeConverter); - String beanName = getTargetBeanName() + "#" + contextFactory.getContextId(); - try { /* @@ -149,27 +167,34 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I * come back when getBean() is called later on */ String targetBeanName = getTargetBeanName(); - GenericBeanDefinition beanDefinition = new GenericBeanDefinition(listableBeanFactory - .getMergedBeanDefinition(targetBeanName)); + GenericBeanDefinition beanDefinition = new GenericBeanDefinition( + listableBeanFactory.getMergedBeanDefinition(targetBeanName)); logger.debug("Rehydrating scoped target: [" + targetBeanName + "]"); - BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(new StringValueResolver() { - public String resolveStringValue(String strVal) { - if (!strVal.contains(PLACEHOLDER_PREFIX)) { - return strVal; - } - if (strVal.startsWith(PLACEHOLDER_PREFIX) && strVal.endsWith(PLACEHOLDER_SUFFIX)) { - // If the whole value is a placeholder it might be - // possible to replace it all in one go as a String - // (e.g. if it's a ref=#{}) - StringBuilder result = new StringBuilder(strVal); - String key = extractKey(strVal); - replaceIfTypeMatches(result, 0, strVal.length() - 1, key, String.class, typeConverter); - return result.toString(); - } - return replacePlaceholders(strVal, contextTypeConverter); - } - }) { + BeanDefinitionVisitor visitor = new BeanDefinitionVisitor( + new StringValueResolver() { + public String resolveStringValue(String strVal) { + if (!strVal.contains(PLACEHOLDER_PREFIX)) { + return strVal; + } + if (strVal.startsWith(PLACEHOLDER_PREFIX) + && strVal.endsWith(PLACEHOLDER_SUFFIX)) { + // If the whole value is a placeholder it might + // be + // possible to replace it all in one go as a + // String + // (e.g. if it's a ref=#{}) + StringBuilder result = new StringBuilder(strVal); + String key = extractKey(strVal); + replaceIfTypeMatches(result, 0, + strVal.length() - 1, key, String.class, + typeConverter); + return result.toString(); + } + return replacePlaceholders(strVal, + contextTypeConverter); + } + }) { protected Object resolveValue(Object value) { if (value instanceof TypedStringValue) { TypedStringValue typedStringValue = (TypedStringValue) value; @@ -178,8 +203,7 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I String visitedString = resolveStringValue(stringValue); value = new TypedStringValue(visitedString); } - } - else { + } else { value = super.resolveValue(value); } return value; @@ -190,10 +214,11 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I beanFactory.registerBeanDefinition(beanName, beanDefinition); // Make the replacements before the target is hydrated visitor.visitBeanDefinition(beanDefinition); - return beanFactory.getBean(beanName); + target = beanFactory.getBean(beanName); + putTargetInContext(target); + return target; - } - finally { + } finally { beanFactory.removeBeanDefinition(beanName); beanFactory = null; // Anything else we can do to clean it up? @@ -201,6 +226,21 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I } + private void putTargetInContext(Object target) { + Object context = contextFactory.getContext(); + if (context instanceof AttributeAccessor) { + ((AttributeAccessor) context).setAttribute(beanName, target); + } + } + + private Object getTargetFromContext() { + Object context = contextFactory.getContext(); + if (context instanceof AttributeAccessor) { + return ((AttributeAccessor) context).getAttribute(beanName); + } + return null; + } + /** * @param value * @param typeConverter @@ -209,12 +249,15 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I protected String convertToString(Object value, TypeConverter typeConverter) { String result = null; try { - // Give it one chance to convert - this forces the default editors to be registered - result = (String) typeConverter.convertIfNecessary(value, String.class); + // Give it one chance to convert - this forces the default editors + // to be registered + result = (String) typeConverter.convertIfNecessary(value, + String.class); } catch (TypeMismatchException e) { // ignore } - if (result== null && typeConverter instanceof PropertyEditorRegistrySupport) { + if (result == null + && typeConverter instanceof PropertyEditorRegistrySupport) { /* * PropertyEditorRegistrySupport is de rigeur with TypeConverter * instances used internally by Spring. If we have one of those then @@ -222,7 +265,8 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I * to. */ PropertyEditorRegistrySupport registry = (PropertyEditorRegistrySupport) typeConverter; - PropertyEditor editor = registry.findCustomEditor(value.getClass(), null); + PropertyEditor editor = registry.findCustomEditor(value.getClass(), + null); if (editor != null) { if (registry.isSharedEditor(editor)) { // Synchronized access to shared editor @@ -231,8 +275,7 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I editor.setValue(value); result = editor.getAsText(); } - } - else { + } else { editor.setValue(value); result = editor.getAsText(); } @@ -247,10 +290,12 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I * @param typeConverter * @return */ - private Object convertFromContext(String key, Class requiredType, TypeConverter typeConverter) { + private Object convertFromContext(String key, Class requiredType, + TypeConverter typeConverter) { Object result = null; Object property = getPropertyFromContext(key); - if (property == null || requiredType.isAssignableFrom(property.getClass())) { + if (property == null + || requiredType.isAssignableFrom(property.getClass())) { result = property; } return result; @@ -267,7 +312,8 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I private String extractKey(String value) { if (value.startsWith(PLACEHOLDER_PREFIX)) { value = value.substring(PLACEHOLDER_PREFIX.length()); - value = value.substring(0, value.length() - PLACEHOLDER_SUFFIX.length()); + value = value.substring(0, value.length() + - PLACEHOLDER_SUFFIX.length()); } return value; } @@ -286,17 +332,28 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I while (first >= 0) { - Assert.state(next > 0, String.format("Placeholder key incorrectly specified: use %skey%s (in %s)", - PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, value)); + Assert + .state( + next > 0, + String + .format( + "Placeholder key incorrectly specified: use %skey%s (in %s)", + PLACEHOLDER_PREFIX, + PLACEHOLDER_SUFFIX, value)); - String key = result.substring(first + PLACEHOLDER_PREFIX.length(), next); + String key = result.substring(first + PLACEHOLDER_PREFIX.length(), + next); - replaceIfTypeMatches(result, first, next, key, String.class, typeConverter); - replaceIfTypeMatches(result, first, next, key, Long.class, typeConverter); - replaceIfTypeMatches(result, first, next, key, Integer.class, typeConverter); + replaceIfTypeMatches(result, first, next, key, String.class, + typeConverter); + replaceIfTypeMatches(result, first, next, key, Long.class, + typeConverter); + replaceIfTypeMatches(result, first, next, key, Integer.class, + typeConverter); // Spring cannot convert from String to Date, so there is an error // here. - replaceIfTypeMatches(result, first, next, key, Date.class, typeConverter); + replaceIfTypeMatches(result, first, next, key, Date.class, + typeConverter); first = result.indexOf(PLACEHOLDER_PREFIX, first + 1); next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1); @@ -307,11 +364,13 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I } - private void replaceIfTypeMatches(StringBuilder result, int first, int next, String key, Class requiredType, + private void replaceIfTypeMatches(StringBuilder result, int first, + int next, String key, Class requiredType, TypeConverter typeConverter) { Object property = convertFromContext(key, requiredType, typeConverter); if (property != null) { - result.replace(first, next + 1, (String) typeConverter.convertIfNecessary(property, String.class)); + result.replace(first, next + 1, (String) typeConverter + .convertIfNecessary(property, String.class)); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/StepScopePerformanceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/StepScopePerformanceTests.java new file mode 100644 index 000000000..52baeb436 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/StepScopePerformanceTests.java @@ -0,0 +1,77 @@ +package org.springframework.batch.core.scope; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +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.ExecutionContext; +import org.springframework.batch.item.ItemStreamReader; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.StopWatch; + +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class StepScopePerformanceTests implements ApplicationContextAware { + + private Log logger = LogFactory.getLog(getClass()); + + private ApplicationContext applicationContext; + + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + + } + + @Before + public void start() throws Exception { + int count = doTest("vanilla", "warmup"); + logger.info("Item count: "+count); + StepSynchronizationManager.register(new StepExecution("step", new JobExecution(0L),1L)); + } + + @Before + @After + public void cleanup() { + StepSynchronizationManager.close(); + } + + @Test + public void testVanilla() throws Exception { + int count = doTest("vanilla", "vanilla"); + logger.info("Item count: "+count); + } + + @Test + public void testProxied() throws Exception { + int count = doTest("proxied", "proxied"); + logger.info("Item count: "+count); + } + + private int doTest(String name, String test) throws Exception { + @SuppressWarnings("unchecked") + ItemStreamReader reader = (ItemStreamReader) applicationContext.getBean(name); + reader.open(new ExecutionContext()); + StopWatch stopWatch = new StopWatch(test); + stopWatch.start(); + int count = 0; + while (reader.read() != null) { + // do nothing + count++; + } + stopWatch.stop(); + reader.close(); + logger.info(stopWatch.shortSummary()); + return count; + } + +} diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-context.xml new file mode 100644 index 000000000..a7692b249 --- /dev/null +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-context.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-input.txt b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-input.txt new file mode 100644 index 000000000..f3307e99c --- /dev/null +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/StepScopePerformanceTests-input.txt @@ -0,0 +1,660 @@ +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spamfoo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam +foo bar spam diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceAwareItemReaderItemStream.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceAwareItemReaderItemStream.java index aa1229a2f..6f8fdbf0e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceAwareItemReaderItemStream.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceAwareItemReaderItemStream.java @@ -18,6 +18,7 @@ package org.springframework.batch.item.file; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; +import org.springframework.batch.item.ItemStreamReader; import org.springframework.core.io.Resource; /** @@ -26,7 +27,7 @@ import org.springframework.core.io.Resource; * * @author Robert Kasanicky */ -public interface ResourceAwareItemReaderItemStream extends ItemReader, ItemStream { +public interface ResourceAwareItemReaderItemStream extends ItemStreamReader { void setResource(Resource resource); }