当前位置: 首页 > 知识库问答 >
问题:

如何在SpringBatch中处理有状态项读取器

秦德海
2023-03-14

我们的SpringBatch作业只有一个步骤,包括ItemReader、ItemProcessor和ItemWriter。我们用不同的参数同时运行同一个作业。ItemReader是有状态的,因为它包含从中读取的输入流。

因此,我们不希望ItemReader的相同html" target="_blank">实例用于每个JobInstance(作业参数)调用。

我不太确定哪种是这种情况的最佳“范围界定”。

1) 该步骤是否应该以@JobScope和ItemReader作为原型进行注释?

2) 这个步骤应该用@StepScope注释,而ItemReader应该是原型吗?

3) Step和ItemReader都应该被标注为原型吗?

最终结果应该是,使用不同的识别参数(即,对于每个新的JobInstance),为每一个新的作业执行创建一个新的ItemReader。

谢谢-美联社_

共有2个答案

姜嘉荣
2023-03-14

没有必要每个组件(步骤、ItemReader、ItemProcencer、ItemWriter)都必须是Spring组件。例如,对于SpringBatch-JavaApi,只有您的作业需要是SpringBean,但您的步骤、阅读器和作家不需要:

    @Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Bean
public Job job() throws Exception {
    return this.jobs.get(JOB_NAME) // create jobbuilder
            .start(step1()) // add step 1
            .next(step2()) // add step 2
            .build(); // create job
}

@Bean
public Job job() throws Exception {
    return this.jobs.get(JOB_NAME) // create jobbuilder
            .start(step1(JOB_NAME)) // add step 1
            .next(step2(JOB_NAME)) // add step 2
            .build(); // create job
}

private Step step1(String jobName) throws Exception {

    return steps.get(jobName + "_Step_1").chunk(10) //
            .faultTolerant() //
            .reader(() -> null) // you could lambdas
            .writer(items -> {
            }) //
            .build();
}

private Step step2(String jobName) throws Exception {
    return steps.get(jobName + "_Step_2").chunk(10) //
            .faultTolerant() //
            .reader(createDbItemReader(ds, sqlString, rowmapper)) //
            .writer(createFileWriter(resource, aggregator)) //
            .build();
}

唯一需要注意的是,在创建JdbcCurserItemReader、FlatFileItemReader/Writer等实例时,必须调用“AfterPropertieSet”方法:

    private static <T> ItemReader<T> createDbItemReader(DataSource ds, String sql, RowMapper<T> rowMapper) throws Exception {
    JdbcCursorItemReader<T> reader = new JdbcCursorItemReader<>();

    reader.setDataSource(ds);
    reader.setSql(sql);
    reader.setRowMapper(rowMapper);

    reader.afterPropertiesSet(); // don't forget
    return reader;
}

private static <T> ItemWriter<T> createFileWriter(Resource target, LineAggregator<T> aggregator) throws Exception {
    FlatFileItemWriter<T> writer = new FlatFileItemWriter();

    writer.setEncoding("UTF-8");
    writer.setResource(target);
    writer.setLineAggregator(aggregator);

    writer.afterPropertiesSet(); // don't forget
    return writer;
}

这样,你就不需要和范围争论了。每个工作都有自己的步骤实例和它们的读者和作家。

这种方法的另一个优点是,您现在可以完全动态地创建工作。

甘骞尧
2023-03-14

下面是从类实例化的角度(从最少的实例到大多数实例)来看的情况:

如果您有多个作业在一个JVM中运行(假设您不在分区步骤中,JobScope就足够了。如果您有一个分区步骤,您需要StepScope。原型在所有场景中都会被过度使用。

然而,如果这些作业在不同的JVM中启动(而不是分区步骤),那么一个简单的单例bean就可以了。

 类似资料:
  • 我想用3个步骤建立一个批次。我想配置这个步骤,就像如果有100条记录,当step1读取、处理和写入一个10块时,step02,然后step03开始和结束,然后再次返回step1,读取下一个块。这在Spring批量可能吗?

  • 我正在尝试重新实现malloc,我需要理解对齐的目的。据我所知,如果内存对齐,代码将执行得更快,因为处理器不必采取额外步骤来恢复被剪切的内存位。我想我理解64位处理器读取64位逐64位内存。现在,让我们想象一下,我有一个有序的结构(没有填充):一个char、一个short、一个char和一个int。为什么short会错位?我们有区块中的所有数据!为什么地址必须是2的倍数。整数和其他类型的问题是一样

  • 我正在使用JpaPagingItemReaderBuilder查询一个DB,结果被插入到另一个DB中。 查询返回的结果没有任何问题,但我得到了一个错误与读取器的返回,在处理器中,您可以检查我的编码和错误下面。 有谁能给我一点启示吗?为什么我不能处理结果?

  • 问题内容: 通过 设计, 人们只能将访问权限限制为仅通过身份验证的用户。 无论如何,当 未经 身份 验证的 用户尝试访问受限页面时,devise会自动导致重定向到 登录 页面。 因此,尝试打开http:// localhost:3000 / users / edit 将导致重定向到http:// localhost:3000 / users / sign_in 。 现在,如果我将链接http://

  • 但我正在寻找一种更优雅的方式来存储存储中的获取状态。 因此,我尝试了另一种方法,并考虑创建一个fetchingActionsReducer,它将每个提取操作添加到存储中的dict(对象),然后状态如下所示: 导出常量loadingTasks=(state={},action)=>{switch(action.type){case start_loading_task:return object.a

  • For example, here’s how you would select the object: And to fetch the counter’s currentValue, we can pass in a string array, where each string plucks a single property from the application state one a