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 中声明的范围内使用之前都会被实例化,并且在其包含范围的生命周期内有效。有两个范围与工件生命周期有关:job
和 step
.
在您的案例中,您可以使用 @Scope("step")
注释您的 CustomItemWriter,并且由于您是 运行 多线程批处理,每个线程都将创建自己的 myCustomItemWriter
实例,该实例将存在仅针对当前执行步骤。
我有一个具有以下定义的批处理作业:
<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 中声明的范围内使用之前都会被实例化,并且在其包含范围的生命周期内有效。有两个范围与工件生命周期有关:job
和 step
.
在您的案例中,您可以使用 @Scope("step")
注释您的 CustomItemWriter,并且由于您是 运行 多线程批处理,每个线程都将创建自己的 myCustomItemWriter
实例,该实例将存在仅针对当前执行步骤。