【问题标题】:How to pass a bean from processor to writer in spring batch?如何在春季批处理中将bean从处理器传递给编写器?
【发布时间】:2019-03-13 00:13:29
【问题描述】:

在我的 spring 批处理代码中,我正在读取一个 csv 文件,将其处理成一个 bean 并尝试在 writer 中获取具有值的 bean。但我无法在作家中获得豆子。 UserVO 是具有来自 csv 文件的值的 bean,我试图将其写入 writer。我也将 bean 初始化为一个公共变量,希望它能被读取器、处理器和写入器处理。甚至在UserVO user = new UserVO(); 之前使用了@Bean@Autowired 注释。请帮我解决这个问题。以下是我的代码,

@EnableBatchProcessing
@Configuration
public class CsvFileToDatabaseConfig {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public DataSource dataSource;

    UserVO user = new UserVO();

    @Bean
    public FlatFileItemReader<UserVO> csvReader() {
         FlatFileItemReader<UserVO> reader = new FlatFileItemReader<UserVO>();
        try{

        reader.setResource(new ClassPathResource("user.csv"));
        reader.setLineMapper(new DefaultLineMapper<UserVO>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                setNames(new String[] { "memberId", "mailId", "fullName", "appCode", "active"});
            }});
            setFieldSetMapper(new BeanWrapperFieldSetMapper<UserVO>() {{
                setTargetType(UserVO.class);
            }});
        }});

        }
        catch(Exception e){
            System.out.println(" Exception in reading " + e.getMessage());
        }
         return reader;
    }


    @Bean
    ItemProcessor<UserVO, UserVO> csvProcessor() {          
        return new Processor();
    }

    @Bean
    public JdbcBatchItemWriter<UserVO> csvWriter(UserVO user) {
         JdbcBatchItemWriter<UserVO> csvWriter = new JdbcBatchItemWriter<UserVO>();
         System.out.println("MEMBER ID --->" + user.memberId);
        return csvWriter;
    }

    @Bean
    public Step csvFileToDatabaseStep() throws Exception {
        LDSService ldsService = new LDSService();

        return stepBuilderFactory.get("csvFileToDatabaseStep")
                .<UserVO, UserVO>chunk(1)
                .reader(csvReader())
                .processor(csvProcessor())
                .writer(csvWriter(user))            
                .build();
    }

    @Bean
    Job csvFileToDatabaseJob(JobCompletionNotificationListener listener) throws Exception {
        return jobBuilderFactory.get("csvFileToDatabaseJob")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .flow(csvFileToDatabaseStep())
                .end()
                .build();
    }

}

【问题讨论】:

  • 您的阅读器创建UserVo 实例,这些实例被传递给处理器,最后传递给编写器。那么,到底为什么你需要像现在这样分享它呢?显然你正在使用 Spring Batch。

标签: java spring spring-boot spring-batch


【解决方案1】:
public class SkipFooterLineItemProcessor implements ItemProcessor<UserVO, UserVO> {


    @Override
    public UserVO process(UserVO item) throws Exception {

       return item;

    }
}

【讨论】:

  • 其实我已经为处理器添加了这部分代码。但现在也以类似的方式为编写器添加了实现 ItemWriter 并覆盖 write()。在 write 方法中,我可以得到 bean :) 谢谢 Janath。
【解决方案2】:

在回答您的问题之前,我想先澄清一下您对事物运作方式的理解似乎有些困惑。

当您为 Spring Batch 组件(读取器、写入器等)定义 Spring bean 时,此时不会发生实际的读取或写入。您只是在定义工作中的步骤要使用的那些 bean。当你写这个时:

@Bean
public FlatFileItemReader<UserVO> csvReader() {
     FlatFileItemReader<UserVO> reader = new FlatFileItemReader<UserVO>();
    try{

    reader.setResource(new ClassPathResource("user.csv"));
    reader.setLineMapper(new DefaultLineMapper<UserVO>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames(new String[] { "memberId", "mailId", "fullName", "appCode", "active"});
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<UserVO>() {{
            setTargetType(UserVO.class);
        }});
    }});

    }
    catch(Exception e){
        System.out.println(" Exception in reading " + e.getMessage());
    }
     return reader;
}

捕获异常并打印Exception in reading 意味着您认为此方法正在读取,而事实并非如此。此方法仅定义步骤将使用的项目阅读器。实际读取将在面向块的步骤自动调用的org.springframework.batch.item.ItemReader#read 方法中完成。作者也是如此(关于System.out.println("MEMBER ID ---&gt;" + user.memberId);)。

话虽如此,您不需要创建UserVO 的实例,您只需指定 CSV 文件的每一行应映射到哪个域类型,阅读器将创建此类型的实例(如M. Deinum 在 cmets 中提到)。所以你需要删除这一行:UserVO user = new UserVO();,你的工作定义应该没问题。

您可以在此处的入门指南中找到类似的用例:https://spring.io/guides/gs/batch-processing/。您将看到无需手动创建域类型Person 的实例。

希望这有助于澄清一些事情。

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 2019-03-26
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多