如何为Spring Batch的Item Reader和Writer实现独立类拆分
实现Spring Batch Reader/Writer的组件化拆分
步骤1:创建独立的Item Reader组件
新建FFItemReader类,标记为@Component并实现ItemReader<Product>接口,把原配置类中的FlatFileItemReader初始化逻辑迁移过来:
import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Component; @Component public class FFItemReader implements ItemReader<Product> { private final FlatFileItemReader<Product> delegateReader; // 构造方法完成Reader配置初始化 public FFItemReader() { delegateReader = new FlatFileItemReader<>(); delegateReader.setLinesToSkip(1); // 跳过CSV表头行 delegateReader.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()); // 复用你已有的字段映射器 delegateReader.setLineMapper(lineMapper); } @Override public Product read() throws Exception { return delegateReader.read(); } }
步骤2:创建独立的Item Writer组件
新建FFItemWriter类,标记为@Component并实现ItemWriter<Product>接口,注入DataSource并完成JdbcBatchItemWriter的初始化:
import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.database.JdbcBatchItemWriter; import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.util.List; @Component public class FFItemWriter implements ItemWriter<Product> { private final JdbcBatchItemWriter<Product> delegateWriter; // 构造方法注入DataSource public FFItemWriter(DataSource dataSource) { delegateWriter = new JdbcBatchItemWriter<>(); delegateWriter.setDataSource(dataSource); delegateWriter.setSql("insert into product_details_output values (:productId, :productName, :productCategory, :productPrice)"); delegateWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider()); // 调用afterPropertiesSet验证配置(JdbcBatchItemWriter要求必须执行此方法) try { delegateWriter.afterPropertiesSet(); } catch (Exception e) { throw new RuntimeException("初始化JdbcBatchItemWriter失败", e); } } @Override public void write(List<? extends Product> items) throws Exception { delegateWriter.write(items); } }
步骤3:修改Batch配置类,注入组件并配置Job/Step
删除原配置类中flatFileItemReader()和jdbcBatchItemWriter()的@Bean方法,改为通过@Autowired注入上述两个组件:
import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; @Configuration public class BatchConfiguration { @Autowired private FFItemReader ffItemReader; @Autowired private FFItemWriter ffItemWriter; @Bean public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new StepBuilder("chunkBasedStep1", jobRepository) .<Product, Product>chunk(3, transactionManager) // 修正原代码泛型不一致问题 .reader(ffItemReader) .writer(ffItemWriter) .build(); } @Bean public Job firstJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new JobBuilder("job1", jobRepository) .start(step1(jobRepository, transactionManager)) .build(); } // 如需配置多个Job,直接新增对应Job/Step的@Bean方法,注入不同的Reader/Writer即可 // 示例: /* @Autowired private AnotherItemReader anotherItemReader; @Autowired private AnotherItemWriter anotherItemWriter; @Bean public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new StepBuilder("chunkBasedStep2", jobRepository) .<Product, Product>chunk(5, transactionManager) .reader(anotherItemReader) .writer(anotherItemWriter) .build(); } @Bean public Job secondJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new JobBuilder("job2", jobRepository) .start(step2(jobRepository, transactionManager)) .build(); } */ }
关键注意事项
- 组件化拆分后,每个Reader/Writer都是Spring容器中的单例Bean,可被多个Job/Step复用。
- 若需要不同配置的Reader/Writer,只需新建对应的
@Component类即可,无需在配置类中重复编写Bean定义。 JdbcBatchItemWriter必须调用afterPropertiesSet()完成初始化,否则会抛出配置未完成的异常。- 确保
ProductFieldSetMapper类已被Spring管理(可标记@Component),或在Reader中直接实例化(如原代码所示)。
内容的提问来源于stack exchange,提问作者Shahrukh Ali
相关产品推荐
相关产品推荐

