RESOLVED - issue BATCH-1185: Job slows when step scope is used
http://jira.springframework.org/browse/BATCH-1185
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> reader = (ItemStreamReader<String>) 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:p="http://www.springframework.org/schema/p" 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.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<bean id="vanilla" class="org.springframework.batch.item.file.FlatFileItemReader">
|
||||
<property name="lineMapper">
|
||||
<bean
|
||||
class="org.springframework.batch.item.file.mapping.PassThroughLineMapper" />
|
||||
</property>
|
||||
<property name="resource" value="classpath:/org/springframework/batch/core/scope/StepScopePerformanceTests-input.txt"></property>
|
||||
</bean>
|
||||
|
||||
<bean id="proxied" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
|
||||
<property name="lineMapper">
|
||||
<bean
|
||||
class="org.springframework.batch.item.file.mapping.PassThroughLineMapper" />
|
||||
</property>
|
||||
<property name="resource" value="classpath:/org/springframework/batch/core/scope/StepScopePerformanceTests-input.txt"></property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.core.scope.StepScope" />
|
||||
|
||||
</beans>
|
||||
@@ -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
|
||||
@@ -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<T> extends ItemReader<T>, ItemStream {
|
||||
public interface ResourceAwareItemReaderItemStream<T> extends ItemStreamReader<T> {
|
||||
|
||||
void setResource(Resource resource);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user