Spring批处理。如何链接具有不同类型的多个itemProcessor?

Posted

技术标签:

【中文标题】Spring批处理。如何链接具有不同类型的多个itemProcessor?【英文标题】:Spring batch .How to chain multiple itemProcessors with diffrent types? 【发布时间】:2021-01-08 13:36:10 【问题描述】:

我必须组成 2 个处理器,如下所示:

processor 1 使用itemProcessor<A,B> 实现itemProcessor 接口(转换数据)。 processor 2 使用itemProcessor<B,B> 实现itemProcessor 接口。(处理转换后的数据)。

CompositeItemProcessor<I, O> 要求委托的类型相同,而且在将其传递给Step 时,该步骤已经配置为固定类型<A,B>

我如何将这些处理器与不同类型链接起来并将其分配给step 处理器?

【问题讨论】:

【参考方案1】:

您需要使用<A, B> 声明您的步骤以及您的复合处理器。这是一个简单的例子:

import java.util.Arrays;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.CompositeItemProcessor;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJobConfiguration 

    @Bean
    public ItemReader<A> itemReader() 
        return new ListItemReader<>(Arrays.asList(new A("a1"), new A("a2")));
    

    @Bean
    public ItemProcessor<A, B> itemProcessor1() 
        return item -> new B(item.name);
    

    @Bean
    public ItemProcessor<B, B> itemProcessor2() 
        return item -> item; // TODO process item as needed
    

    @Bean
    public ItemProcessor<A, B> compositeItemProcessor() 
        CompositeItemProcessor<A, B> compositeItemProcessor = new CompositeItemProcessor<>();
        compositeItemProcessor.setDelegates(Arrays.asList(itemProcessor1(), itemProcessor2()));
        return compositeItemProcessor;
    

    @Bean
    public ItemWriter<B> itemWriter() 
        return items -> 
            for (B item : items) 
                System.out.println("item = " + item.name);
            
        ;
    

    @Bean
    public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) 
        return jobs.get("job")
                .start(steps.get("step")
                        .<A, B>chunk(2)
                        .reader(itemReader())
                        .processor(compositeItemProcessor())
                        .writer(itemWriter())
                        .build())
                .build();
    

    public static void main(String[] args) throws Exception 
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    
    
    class A 
        String name;
        public A(String name)  this.name = name; 
    

    class B 
        String name;
        public B(String name)  this.name = name; 
    


【讨论】:

感谢您的回答,但是它并没有解决问题,我已经看到了compositeItemProcessor 的源代码,它是一个泛型类型,在它期望代表的处理方法中itemProcessors 与 声明的类型相同,这不是我的情况,我有不同类型的 itemProcessors 您询问了如何在组合中使用ItemProcessor&lt;A, B&gt;ItemProcessor&lt;B, B&gt;,这正是示例所显示的。您在哪里看到要求代表具有相同类型的复合材料?代码如下:github.com/spring-projects/spring-batch/blob/…,复合类型为&lt;I, O&gt;,委托类型为&lt;?, ?&gt; 只要复合的类型与步骤所期望的相同,您之间有多少个委托处理器都没有关系:如果步骤读取 A 类型的项目并写入项目D 类型(例如 .&lt;A, D&gt;chunk(5)),您可以将处理器 A-&gt;BB-&gt;CC-&gt;D 作为 CompositeItemProcessor&lt;A, D&gt; 的代表,只要一个处理器的输出类型与链中下一个处理器的输入类型。 感谢 Mahmoud 先生,我在另一部分遇到了问题,抱歉,这已经解决了问题 嗨,我面临着类似的情况,我正在尝试几天来找到解决方案。在以下情况下是否可能或正确的方法是:读取 XML -> ComplexObject -> List -> Model -> Write。是否可以使用 ItemProcessors 做到这一点?

以上是关于Spring批处理。如何链接具有不同类型的多个itemProcessor?的主要内容,如果未能解决你的问题,请参考以下文章

您将如何使用 Spring Boot 处理仅具有可选查询参数的 REST API?

Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用

如何在没有 xml 的 Java 配置中使用具有不同数据并具有两个 JdbcBatchItemWritter 的 Spring 批处理 CompositeItemWriter

如何使用基于类的配置设置具有不同基础包、transactionManagerRef 的多个 Spring Data JPA?

如何使用 Spring 管理具有不同 jdbc(或休眠?)的多个“运行时注意到”数据库连接?

处理具有多个活动的深层链接