我想知道这样的流程:
ItemReader -> ItemProcessor -> ItemWriter
其中每个都是实现等效接口的自定义类,并且在面向块的步骤中,何时将调用每个构造函数?
到目前为止我理解(如果我错了,请纠正我),ItemWriter构造函数将在步骤开始时调用一次,对于每个chunk,write()将仅被调用。此规则适用于其他2?
答案 0 :(得分:2)
Vinay的回答是正确的,但需要一些细化。
对于reader-processor-> writer Spring调用默认构造函数(让我们忽略@PostConstruct等) 范围(“步骤”),顾名思义是为每一步创建一个新bean。 步骤不必与线程一对一,例如,假设我有以下读取器 - 处理器 - >编写器
@Component
@Scope("step")
public class DoNothingItemReader implements ItemReader<String>{
public DoNothingItemReader() {
LOGGER.info(String.format("New %s created"
,ClassUtils.getShortName(this.getClass())));
}
@Override
public String read() throws Exception{
LOGGER.info("Nothing to read...");
..
}
}
@Component
@Scope("step")
public class DoNothingItemProcessor implements ItemProcessor<String, String> {
public DoNothingItemProcessor() {
LOGGER.info(String.format("New %s created"
,ClassUtils.getShortName(this.getClass())));
}
@Override
public String process(String i) throws Exception {
LOGGER.info("Nothing to process...");
return i;
}
}
@Component
@Scope("step")
public class DoNothingItemWritter implements ItemWriter<String[]> {
public DoNothingItemWritter() {
LOGGER.info(String.format("New %s created"
,ClassUtils.getShortName(this.getClass())));
}
@Override
public void write(List<? extends String[]> items) throws Exception {
LOGGER.info("Nothing to write...");
}
现在我们在两个步骤中重复使用上述内容,例如
<batch:job id="testScopStep">
<batch:step id="step1" next="step2">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="doNothingItemReader"
processor="doNothingItemProcessor"
writer="doNothingItemWritter" commit-interval="3">
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:step id="step2">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="doNothingItemReader"
processor="doNothingItemProcessor"
writer="doNothingItemWritter" commit-interval="3">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
构造函数将被调用两次,以便读取器 - >处理器 - >编写器
日志将是
[SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] launched>
[SimpleStepHandler] - <Executing step: [step1]>
[DoNothingItemReader] - <New DoNothingItemReader created>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemProcessor] - <New DoNothingItemProcessor created>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemWritter] - <New DoNothingItemWritter created>
[DoNothingItemWritter] - <Nothing to write...>
[SimpleStepHandler] - <Executing step: [step2]>
[DoNothingItemReader] - <New DoNothingItemReader created>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemProcessor] - <New DoNothingItemProcessor created>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemWritter] - <New DoNothingItemWritter created>
[DoNothingItemWritter] - <Nothing to write...>
[SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] completed
现在考虑使用复合编写器时的以下场景
<batch:job id="testScopStep">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="doNothingItemReader"
processor="doNothingItemProcessor"
writer="compositeWriter" commit-interval="3">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
这里构造函数只会被调用一次 日志将显示
[SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] launched>
[SimpleStepHandler] - <Executing step: [step1]>
[DoNothingItemReader] - <New DoNothingItemReader created>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemReader] - <Nothing to read...>
[DoNothingItemProcessor] - <New DoNothingItemProcessor created>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemProcessor] - <Nothing to process...>
[DoNothingItemWritter] - <New DoNothingItemWritter created>
[DoNothingItemWritter] - <Nothing to write...>
[DoNothingItemWritter] - <Nothing to write...>
[SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] completed
所以在这种情况下我们应该小心考虑我们正在分享同一位作家。
答案 1 :(得分:1)
ItemWriter,Reader和Writer都是Spring bean。如果您使用@component
标记它们,则所有这些都只创建一次,并在创建ApplicationContext时调用构造函数。虽然您可以指定不同的范围,例如@scope("step")
。这将使每个线程在多线程批处理中都有自己的组件