【问题标题】:Multiple writers for different types in the same Spring Batch step在同一个 Spring Batch 步骤中针对不同类型的多个编写器
【发布时间】:2021-05-08 17:47:45
【问题描述】:

我正在编写一个Spring Batch 应用程序,其工作流程如下:

  1. 读取A 类型的一些项目(使用FlatFileItemReader<A>)。
  2. 处理项目,将其从 A 转换为 B
  3. 写入B类型的已处理项目(使用JdbcBatchItemWriter<B>
  4. 最终,我应该调用外部服务(一个 RESTful API,但它可以是 SimpleMailMessageItemWriter<A>使用来自源类型的数据 A

如何配置这样的工作流程?

到目前为止,我找到了以下解决方法:

  • 配置一个CompositeItemWriter<B>,它代表:
    1. 实际ItemWriter<B>
    2. 自定义ItemWriter<B> 实现将B 转换回A,然后写入A

但这是一个繁琐的解决方案,因为它迫使我:

  • 重复处理逻辑:从AB 再返回。
  • B 内部偷偷隐藏源对象A 的一些属性,污染域模型。

注意:由于我的A 的自定义项目写入器需要调用外部服务,所以我想在B 写入成功后执行此操作。

这里是批量配置代码的相关部分。

@Bean
public Step step(StepBuilderFactory steps, ItemReader<A> reader, ItemProcessor<A, B> processor, CompositeItemWriter<B> writer) {
    return steps.get("step")
            .<A, B>chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
}

@Bean
public CompositeItemWriter<B> writer(JdbcBatchItemWriter<B> jdbcBatchItemWriter, CustomItemWriter<B, A> customItemWriter) {
    return new CompositeItemWriterBuilder<B>()
            .delegates(jdbcBatchItemWriter, customItemWriter)
            .build();
}

【问题讨论】:

    标签: spring spring-batch


    【解决方案1】:

    对于您的用例,我会将 A 和 B 封装在一个包装器类型中,例如 AB:

    class AB {
       private A originalItem;
       private B transformedItem;
    }
    

    这样,您将拥有:ItemReader&lt;A&gt;ItemProcessor&lt;A, AB&gt;ItemWriter&lt;AB&gt;。处理器创建 AB 的实例,其中保留对原始项目的引用。然后,作者可以访问这两种类型并根据需要委托给JdbcBatchItemReader&lt;B&gt;SimpleMailMessageItemWriter&lt;A&gt;,例如:

    class ABItemWriter implements ItemWriter<AB> {
        private JdbcBatchItemWriter<B> jdbcBatchItemWriter;
        private SimpleMailMessageItemWriter mailMessageItemWriter;
        // constructor with delegates
    
        @Override
        public void write(List<? extends AB> items) throws Exception {
            jdbcBatchItemWriter.write(getBs(items));
            mailMessageItemWriter.write(getAs(items)); // this would not be called if the jdbc writer fails
        }
    }
    

    getAsgetBs 方法将从 AB 中提取 A/B 类型的项目。为胜利而封装!顺便说一句,Java 记录对于 AB 类型是一个不错的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      相关资源
      最近更新 更多