Spring Batch ItemReader list processed only once

泄露秘密 提交于 2019-12-05 10:33:21
Luca Basso Ricci

The problem is that you marked your reader as scope="prototype". It should be scope="step".

In Spring-batch there are only two scopes: singleton (the default) and step.

From the javadoc:

StepScope:
Scope for step context. Objects in this scope use the Spring container as an object factory, so there is only one instance of such a bean per executing step. All objects in this scope are (no need to decorate the bean definitions).

and

Using a scope of Step is required in order to use late binding since the bean cannot actually be instantiated until the Step starts, which allows the attributes to be found.

During the Spring context startup look at your log and you will see this line:

INFO: Done executing SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql] in 9 ms.
Reading data list [doc1.xkbml, doc2.xkbml, doc3.xkbml]

as you can see your reader has already been created and managed as a singleton; dynamic beans in spring-batch context should be managed with the special step scope so that Spring will create a fresh copy of the bean every time a step is executed.

In your reader, ListItemReader.read() is written as:

public T read() {
  if (!list.isEmpty()) {
    return list.remove(0);
  }
  return null;
}

In each read items are removed from original list! The reader is constructed once and, on second job execution, the list is empty!

Just an additional information: you can also use JavaConfig instead of the xml config file, and annotate the reader bean declaration with @StepConfig.

ex:

@Configuration
@EnableBatchProcessing
public class MyConfig {
...

    @Bean
    @StepScope
    public ItemReader<HeadingBreakevenAssociation> readerHeadingBreakevenAssociationList(){
         ItemReader<Person> itemReader = new ListItemReader<Person>(myList);

          return itemReader;
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!