2016-08-05 50 views
4

我有一个需求,我需要根据剩余的处理文件来处理文件,我在其中获取文件的名称,我将它添加到作业参数并在创建bean时使用它。Spring批处理步骤作用域如何工作

我正在创建步骤作用域Bean(读者,作家)和使用作业参数。我在新线程中启动作业,因为我使用异步任务exceutor来启动作业,我的问题是bean当我们定义@StepScope

jobParametersBuilder.addString("fileName", request.getFileName()); 
jobExecution = jobLauncher.run(job, jobParametersBuilder.toJobParameters()); 
@Bean 
public JobLauncher jobLauncher() { 
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); 
    jobLauncher.setJobRepository(jobRepository()); 
    jobLauncher.setTaskExecutor(asyncTaskExecutor()); 
    return jobLauncher; 
} 

@Bean 
@StepScope 
public ItemWriter<Object> writer(@Value ("#{jobParameters['fileName']}"String fileName) { 
    JdbcBatchItemWriter<Object> writer = new JdbcBatchItemWriter<>(); 
    writer.setItemSqlParameterSourceProvider(
     new BeanPropertyItemSqlParameterSourceProvider<Object>()); 
    writer.setSql(queryCollection.getquery()); 
    writer.setDataSource(dataSource(fileName)); 
    return writer; 
} 

回答

15

弹簧批次StepScope对象是一个是唯一的一个特定的步骤,而不是一个单由弹簧来创建。正如你可能知道的那样,Spring中的默认bean作用域是一个单例。但通过指定一个弹簧批处理组件为StepScope意味着Spring Batch将使用弹簧容器为每个步骤执行实例化该组件的新实例。

这对于参数后期绑定通常很有用,其中可以在StepContextJobExecutionContext级别指定参数,并且需要替代占位符,这很像您的文件名要求示例。

使用StepScope的另一个有用的理由是当您决定在并行步骤中重复使用相同的组件时。如果组件管理任何内部状态,则重要的是它基于StepScope,以便一个线程不会损害另一个线程管理的状态(例如,给定步骤的每个线程都有其自己的StepScope组件实例)。

相关问题