繁体   English   中英

在Spring Batch中调用ItemReader,ItemProcessor,ItemWriter的构造函数时?

[英]When constructors for ItemReader, ItemProcessor, ItemWriter are called in Spring Batch?

我想知道这样的流程:

ItemReader -> ItemProcessor -> ItemWriter 

其中每个都是实现等效接口的自定义类,并且在面向块的步骤中,何时将调用每个构造函数?

到目前为止我理解(如果我错了,请纠正我),ItemWriter构造函数将在步骤开始时调用一次,对于每个chunk,write()将仅被调用。 这个规则适用于其他2个?

Vinay答案是正确的,但需要一些细化。

对于reader-processor-> writer,Spring调用默认构造函数(让我们忽略@PostConstruct等)Scope(“step”),顾名思义就是为每一步创建一个新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

所以在这种情况下我们应该小心考虑我们正在共享同一位作家。

ItemWriter,Reader和Writer都是Spring bean。 如果已使用@component标记它们,则所有这些都只创建一次,并在创建ApplicationContext时调用构造函数。 虽然您可以指定不同的范围,例如@scope("step") 这将使每个线程在多线程批处理中拥有自己的组件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM