java – Spring Batch的ItemWriter是一个单例类吗?

我有一个具有以下定义的批处理作业:

<batch:job id="job">
    <batch:split id="main" task-executor="simpleAsyncTaskExecutor">
        <batch:flow>
            <batch:step id="getAccountDetails">
                <batch:tasklet ref="getAccountDetailsTasklet"/>
            </batch:step>
        </batch:flow>
        <batch:flow>
            <batch:step id="processAccounts">
                <batch:tasklet transaction-manager="transactionManager" task-executor="threadPoolTaskExecutor" throttle-limit="${processor.maxThreads}">
                    <batch:chunk reader="queueReader" writer="myCustomItemWriter" commit-interval="${processor.commitInterval}"/>
                </batch:tasklet>
            </batch:step>
        </batch:flow>
    </batch:split>
</batch:job>

myCustomItemWriter基本上通过queueReader传递的帐户列表并将它们提交到数据库.

该作业被缩放为并行运行该块的100个线程.在myCustomItemWriter的类中,我有一个私有属性,它维护它处理的每个帐户的特定BigDecimal属性的总和.因此,如果有10000个帐户,我将有100个线程,每个处理100个帐户.我想为所有这10000个帐户捕获此属性的总和.

这是我的问题:是ItemWriter单例(因此,只是一个保持这个总和的私有属性就足够了)?如果没有,我应该将我的计数器定义为AtomicReference bean并将其注入我的编写器中,以便在所有100个线程中注入相同的属性实例?

最佳答案 如果使用@Component注释编写器,则默认范围将为singleton.

但是,所有批处理工件在它们在Job XML中声明的范围内使用之前都会被实例化,并且在其包含范围的生命周期内有效.有两个与工件生命周期相关的范围:作业和步骤.

在你的案例中,你可以使用@Scope(“step”)注释你的CustomItemWriter,并且由于你正在运行一个多线程批处理,每个线程将创建自己的myCustomItemWriter实例,它只适用于当前执行步骤.

点赞