javaspring-bootspring-batchbatch-processingflatfilereader

How to create Spring Batch separate class implementation for item reader


I am new to spring batch and i have created basic batch implementation where I have added flat file item reader and reading data from csv file and then writing data to data base using item write.

But all the beans are present in batch config itself so, wanted to create separate class for item reader and item writer and mark them as component and the I can Autowire in my batch config class.

By doing this I can have multiple jobs config in same class and implementation of reader and writer in separate classes.

Spring Batch Config

@Configuration
public class BatchConfiguration {

@Autowired
public DataSource dataSource;

@Bean
    public ItemReader<Product> flatFileItemReader() {

        FlatFileItemReader<Product> itemReader = new FlatFileItemReader<>();
        itemReader.setLinesToSkip(1);
        itemReader.setResource(new ClassPathResource("/data/Product_Details.csv"));

        DefaultLineMapper<Product> lineMapper = new DefaultLineMapper<>();

        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setNames("product_id", "product_name", "product_category", "product_price");

        lineMapper.setLineTokenizer(lineTokenizer);
        lineMapper.setFieldSetMapper(new ProductFieldSetMapper());

        itemReader.setLineMapper(lineMapper);

        return itemReader;
    }

@Bean
    public JdbcBatchItemWriter<Product> jdbcBatchItemWriter() {
        JdbcBatchItemWriter<Product> itemWriter = new JdbcBatchItemWriter<>();
        itemWriter.setDataSource(dataSource);
        itemWriter.setSql("insert into product_details_output values (:productId, :productName, :productCategory, :productPrice)");
        itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
        return itemWriter;
    }

@Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
        return new StepBuilder("chunkBasedStep1", jobRepository)
                .<Product,OSProduct>chunk(3, transactionManager)
                .reader(flatFileItemReader())
                .writer(jdbcBatchItemWriter())
                .build();
    }

    @Bean
    public Job firstJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
        return new JobBuilder("job1", jobRepository)
                .start(step1(jobRepository, transactionManager))
                .build();
    }
}

I don`t want to create flatFileItemReader as bean instead create an item reader class mark it as @Component and then @Autowired in batch.

Something like this.

BatchConfiguration.java

@Autowired
private FFItemReader ffItemReader;
@Autowired
private FFItemWriter ffItemWriter;

@Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
        return new StepBuilder("chunkBasedStep1", jobRepository)
                .<Product,OSProduct>chunk(3, transactionManager)
                .reader(ffItemReader)
                .writer(ffItemWriter)
                .build();
    }

Solution

  • You can just create a class that extends FlatFileItemReader and annotate it with @Component

    public class MyItemReader extends FlatFileItemReader<Product> {
    
    public MyItemReader() {
        setLinesToSkip(1);
        setResource(new ClassPathResource("/data/Product_Details.csv"));
    
        DefaultLineMapper<Product> lineMapper = new DefaultLineMapper<>();
    
        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setNames("product_id", "product_name", "product_category", "product_price");
    
        lineMapper.setLineTokenizer(lineTokenizer);
        lineMapper.setFieldSetMapper(new ProductFieldSetMapper());
    
        setLineMapper(lineMapper);
    }