来自Spring Batch – Tasklets vs Chunks的教程,当定义一个
ItemReader
、ItemProcessor
、ItemWriter
时,我们是否应该给他们一个@StepScope
的注释?
让我举个例子代码:
LineReader 只有一个实例,但它有一个成员
fu
。那么如果在多线程环境下,会不会报错?
为什么在这个教程中,没有被
@StepScope
注释?
....
@Bean // here is no @StepScope, but I think it should have a @StepScope
public ItemReader<Line> itemReader() {
return new LineReader();
}
@Bean
protected Step processLines(ItemReader<Line> reader, ItemProcessor<Line, Line> processor, ItemWriter<Line> writer) {
return steps.get("processLines").<Line, Line> chunk(2)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
....
public class LineReader implements ItemReader<Line>, StepExecutionListener {
private final Logger logger = LoggerFactory.getLogger(LineReader.class);
private FileUtils fu;
@Override
public void beforeStep(StepExecution stepExecution) {
fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv");
logger.debug("Line Reader initialized.");
}
@Override
public Line read() throws Exception {
Line line = fu.readLine();
if (line != null) logger.debug("Read line: " + line.toString());
return line;
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
fu.closeReader();
logger.debug("Line Reader ended.");
return ExitStatus.COMPLETED;
}
}
Q1:在定义ItemReader、ItemProcessor、ItemWriter的时候,要不要给它们加上@StepScope的注解?
中的注释任何使用后期绑定的 bean 都必须声明为 scope="step"。有关详细信息,请参阅步骤范围。 Step bean 不应该是步作用域的。如果在步骤定义中需要后期绑定,则该步骤的组件(tasklet、项目读取器或写入器等)应该是范围限定的组件。
Q2:如果itemReader只有一个实例,在多线程环境下,会报错吗?
如果作业正在运行并且读取器是单例的,并且您使用多线程读取源,这取决于您如何划分数据,如果数据隔离正确则不会发生问题。
PS:在多线程或分区步骤中使用作业范围的 beans 时确实有一些实际限制。请参阅job-scope session
中的注释spring batch @bean 在你启动服务器时只初始化一次所以如果你想更新 @bean 并在主体函数中初始化数据,比如 ItemReader,...使用 @StepScope