我有一个包含大量xml文件的文件夹。我想配置分区以创建许多分区,每个分区将处理可配置数量的文件。分区工作罚款(我检查调试模式并返回正确的执行上下文)。但问题是,尽管分区器创建了多个执行上下文,但步骤仍在执行多次。在这个例子中,我只有3个xml文件。每个分区将处理2个文件。 我将整个项目上传到github:https://github.com/tungtran89/spring-batch-partition
请给我建议,谢谢!
这是分区程序
public class FilePartitioner implements Partitioner {
private String xmlFolderLocation;
private int filePerThread;
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
Assert.hasLength(xmlFolderLocation);
Map<String, ExecutionContext> executionContexts = new HashMap<String, ExecutionContext>();
File xmlDir = new File(xmlFolderLocation);
if (xmlDir.isDirectory()) {
File[] files = xmlDir.listFiles();
int fileCount = 0;
int totalFileCount = 0;
int partitionCount = 0;
Map<String, String> chunk = new HashMap<String, String>();
for (File file: files) {
if (file.isFile()) {
if (fileCount < filePerThread && totalFileCount < files.length) {
totalFileCount++;
chunk.put(file.getName(), file.getAbsolutePath());
fileCount = chunk.size();
}
if (fileCount == filePerThread || totalFileCount == files.length) {
// load enough file to this partition.
// create a new partition by creating new ExecutionContext and new chunk
partitionCount++;
ExecutionContext stepExecutionContext = new ExecutionContext();
stepExecutionContext.put("chunk", chunk);
chunk = new HashMap<String, String>();
executionContexts.put(String.valueOf("partition" + partitionCount), stepExecutionContext);
fileCount = 0;
}
}
}
}
return executionContexts;
}
}
弹簧配置文件
<bean id="filePartitioner" class="com.tung.FilePartitioner" scope="step">
<property name="xmlFolderLocation" value="target\test-classes\data\XML_FILES"/>
<property name="filePerThread" value="2"/>
</bean>
<bean id="xmlLoadReader" scope="step" class="com.tung.XMLPrintingLoadReader">
<property name="chunk" value="#{stepExecutionContext['chunk']}"/>
</bean>
<bean id="xmlProcessor" scope="step" class="com.tung.XMLPrintingFileProcessor"/>
<bean id="xmlWriter" scope="step" class="com.tung.XMLPrintingWriter"/>
<bean id="xmlLoadTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="5" />
</bean>
<batch:step id="slaveStep">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="xmlLoadReader" processor="xmlProcessor" writer="xmlWriter" commit-interval="5"/>
</batch:tasklet>
</batch:step>
<batch:job id="xmlLoader">
<batch:step id="master">
<batch:partition step="slaveStep" partitioner="filePartitioner">
<batch:handler grid-size="2" task-executor="xmlLoadTaskExecutor"/>
</batch:partition>
</batch:step>
</batch:job>
读者
public class XMLPrintingLoadReader implements ItemReader<List<File>> {
private static Logger logger = LoggerFactory.getLogger(XMLPrintingLoadReader.class);
private static int instanceCount = 0;
private int readMethodInvocationCount = 0;
private final int instanceId = instanceCount;
private Map<String, String> chunk;
public XMLPrintingLoadReader() {
instanceCount++;
}
@Override
public List<File> read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
synchronized (this) {
readMethodInvocationCount++;
}
logger.info("Thread " + Thread.currentThread().getName() + " is invoking method read() " +
"of com.tung.XMLPrintingLoadReader[" + instanceId + "] " + readMethodInvocationCount + " times.");
List<File> fileList = new ArrayList<File>();
for (Map.Entry<String, String> entry : chunk.entrySet()) {
File file = new File(entry.getValue());
fileList.add(file);
}
return fileList;
}
public Map<String, String> getChunk() {
return chunk;
}
public void setChunk(Map<String, String> chunk) {
this.chunk = chunk;
}
}
日志文件:
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 1 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 1 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 2 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 2 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 3 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 3 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 4 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 4 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 5 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 5 times
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 6 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 6 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 7 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 7 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 8 times.
INFO XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 8 times.