我正在开发几年前由以前的团队开发的 Spring 批处理程序。 主要的两个文件如下。 RewardsAccumulationReaderConfig 类实现 ItemReader 接口,其中 read() 方法返回 null。但同时,该类有一个@Bean方法rewardsAccumulationReader(),它注册一个读取实际数据进行处理的bean。
我认为该程序不必要地使用了多个@Bean注释以及RewardsAccumulationReaderConfig上的@Configuration。程序确实运行没有问题。我不明白的部分是创建类的实例:
new RewardsAccumulationReaderConfig();
返回通过其 bean 方法之一注册的 bean:rewardsAccumulationReader()?这样的bean不是需要@Autowired或者通过ApplicationContext访问吗?
BatchConfig.java
@EnableBatchProcessing
@Configuration
@EnableScheduling
public class BatchConfig {
@Scheduled(cron = "${scheduler.cronExpression}", zone = "America/New_York")
public void processRewardsTransactionBatchRetry() {
JobParameters param = new JobParametersBuilder().addString("JobID",
REWARDS_ACCUMULATION_SERVICE.concat(String.valueOf(System.currentTimeMillis()))).toJobParameters();
try {
JobExecution execution = jobLauncher.run(rewardsTransactionBatchRetryJob(), param);
} catch (Exception e) {
...
}
}
@Bean
public Job rewardsTransactionBatchRetryJob() {
return jobs
.get("chunksJob")
.start(processRewardsTransaction(readerForRewardsAccumulation(), writerForRewardsAccumulation()))
.build();
}
@Bean
public Step processRewardsTransaction(ItemReader<RewardTransactionRecon> rewardsAccumulationReader,
ItemWriter<RewardTransactionRecon> rewardsAccumulationWriter) {
return steps.get("processRewardsTransaction").<RewardTransactionRecon, RewardTransactionRecon>chunk(chunkSize)
.reader(rewardsAccumulationReader)
.writer(rewardsAccumulationWriter)
.taskExecutor(taskExecutor())
.build();
}
@Bean(name = "rewardsAccumulationReader")
@StepScope
public ItemReader<RewardTransactionRecon> readerForRewardsAccumulation() {
return new RewardsAccumulationReaderConfig();
}
@Bean(name = "rewardsAccumulationWriter")
@StepScope
public ItemWriter<RewardTransactionRecon> writerForRewardsAccumulation() {
return new RewardsAccumulationWriterConfig();
}
}
// RewardsAccumulationReaderConfig.java
@Configuration
public class RewardsAccumulationReaderConfig implements ItemReader<RewardTransactionRecon> {
....
@Bean(name = "rewardsAccumulationReader")
@StepScope
public ItemReader<RewardTransactionRecon> rewardsAccumulationReader(@Qualifier("azureDataSource") DataSource datasource) {
...
return new JdbcPagingItemReaderBuilder<RewardTransactionRecon>()
.name("RewardsAccumulationReader")
.dataSource(datasource)
.queryProvider(queryProvider)
.parameterValues(parameter)
.sortKeys(Collections.singletonMap("event_id", Order.ASCENDING))
.rowMapper(buildRowMapper())
.build();
}
@Override
public RewardTransactionRecon read() throws Exception {
return null;
}
}
你说得对,有一些错误。
1 - RewardsAccumulationReaderConfig 不应实现 ItemReader,因为它是注册 ItemReader bean 的简单 @Configuration 类。 删除它并从中删除 read() 方法。顺便说一句,这解释了为什么 BatchConfig 中的 readerForRewardsAccumulation() 方法返回 ItemReader。
2 - 从 BatchConfig 中删除 readerForRewardsAccumulation() 方法,唯一需要实例化 RewardsAccumulationReaderConfig 的情况是后者对组件扫描不可见时。
3 - writerForRewardsAccumulation 方法的情况相同。
祝你好运。