Spring Batch 的 ItemWriter 是单例 class 吗?

Is Spring Batch's ItemWriter a singleton class?

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

<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 的 class 中,我有一个私有 属性,它维护它处理的每个帐户的特定 BigDecimal 属性 的总和。所以如果有 10000 个帐户,我将有 100 个线程,每个线程处理 100 个帐户。我想为所有这 10000 个帐户捕获此 属性 的总和。

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

如果您使用 @Component 注释您的编写器,则默认范围将是单例。

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

在您的案例中,您可以使用 @Scope("step") 注释您的 CustomItemWriter,并且由于您是 运行 多线程批处理,每个线程都将创建自己的 myCustomItemWriter 实例,该实例将存在仅针对当前执行步骤。