[英]When constructors for ItemReader, ItemProcessor, ItemWriter are called in Spring Batch?
I was wondering for a flow like this: 我想知道这样的流程:
ItemReader -> ItemProcessor -> ItemWriter
where each one of those is a custom class implementing the equivalent interface and in a chunk-oriented step, When each constructor will be called? 其中每个都是实现等效接口的自定义类,并且在面向块的步骤中,何时将调用每个构造函数?
As I understand so far(correct me if I'm wrong) the ItemWriter constructor will be called once in the beginning of the step and for each chunk, write() will be called only. 到目前为止我理解(如果我错了,请纠正我),ItemWriter构造函数将在步骤开始时调用一次,对于每个chunk,write()将仅被调用。 This rule applies for the other 2? 这个规则适用于其他2个?
Vinay answer is correct but need some elaboration. Vinay答案是正确的,但需要一些细化。
For reader-processor->writer Spring calls the default constructor (let's ignore @PostConstruct etc.) Scope(“step”), as the name implies is creating a new bean for every step. 对于reader-processor-> writer,Spring调用默认构造函数(让我们忽略@PostConstruct等)Scope(“step”),顾名思义就是为每一步创建一个新bean。 Step does not have to be one to one with thread, for example let's say I have the following reader-processor->writer 步骤不必与线程一对一,例如,假设我有以下读取器 - 处理器 - >编写器
@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...");
}
Now we reuse this above in two steps eg 现在我们分两步重复使用上述步骤,例如
<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>
The constructor will be called twice for ever reader->processor->writer 对于读者 - >处理器 - >编写器,构造函数将被调用两次
The log will be 日志将是
[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
Now consider the following scenario when we are using a composite writer 现在考虑使用复合编写器时的以下场景
<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>
Here The constructors will be called only once. 这里构造函数只会被调用一次。
The log will display 将显示日志
[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
So in such case we should be careful taking in to consideration we are sharing the same writer. 所以在这种情况下我们应该小心考虑我们正在共享同一位作家。
ItemWriter, Reader and Writer are all Spring beans. ItemWriter,Reader和Writer都是Spring bean。 If you have marked them with @component
then all of them created once only and constructor is called when you create ApplicationContext. 如果已使用@component
标记它们,则所有这些都只创建一次,并在创建ApplicationContext时调用构造函数。 Though there are different scope you can specify like @scope("step")
. 虽然您可以指定不同的范围,例如@scope("step")
。 This will make each thread will have their own component in Multi-threaded batch 这将使每个线程在多线程批处理中拥有自己的组件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.