我使用Spring Batch引导示例。在这个例子中,我希望将基于XML的应用程序转换为基于注释的应用程序。然而,我正在努力配置使用@Bean在步骤创建确切的配置。
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="paymentDataReader" writer="paymentDataWriter" commit-interval="100000">
<batch:listeners>
<batch:listener ref="paymentingStepExecutionListener" />
</batch:listeners>
</batch:chunk>
</batch:tasklet>
<batch:next on="COMPLETED" to="sendpaymentingBatchFiles" />
</batch:step>
作业配置。JAVA
@Configuration
public class JobConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;
@Bean
@StepScope
public PaymentContextTasklet paymentContextTasklet() {
return new PaymentContextTasklet();
}
// Either execute for "Payment" or "Order"
@Bean
public ContextDecider contextDecider() {
return new ContextDecider();
}
@Bean
public JdbcPagingItemReader<Payment> pagingItemReader(){
JdbcPagingItemReader<Payment> reader = new JdbcPagingItemReader<>();
reader.setDataSource(this.dataSource);
reader.setFetchSize(10);
reader.setRowMapper(new PaymentRowMapper());
MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
queryProvider.setSelectClause("select paymentId, amount, customerId, paymentDate");
queryProvider.setFromClause("from payment");
reader.setQueryProvider(queryProvider);
return reader;
}
@Bean
public ItemWriter<Payment> paymentItemWriter(){
return items -> {
for(Payment c : items) {
System.out.println(c.toString());
}
};
}
@Bean
public PaymentStepExecutionListener paymentStepExecutionListener() {
return new PaymentStepExecutionListener();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<Payment, Payment>chunk(10)
.reader(pagingItemReader())
.writer(paymentItemWriter())
.tasklet(paymentStepExecutionListener())
.rea
.build();
}
@Bean
@StepScope
public PaymentDataTasklet paymentDataTasklet() {
return new PaymentDataTasklet();
}
@Bean
public Step paymentContextStep() {
return stepBuilderFactory.get("paymentContextStep")
.tasklet(paymentContextTasklet())
.build();
}
@Bean
public Step paymentDataStep() {
return stepBuilderFactory.get("paymentDataStep")
.tasklet(paymentDataTasklet())
.build();
}
@Bean
public Step endStep() {
return stepBuilderFactory.get("endStep")
.tasklet(null)
.build();
}
@Bean
public Job paymentDataBatchJob() {
return jobBuilderFactory.get("paymentDataBatchJob")
.start(paymentContextStep())
.next(contextDecider())
.on("Payment").to(paymentDataStep()).on("COMPLETED").to(endStep)
.from(contextDecider())
.on("Order").to(endStep()).end()
.build();
}
}
感谢@Mahmoud Ben Hassine。我意识到我应该在listener
而不是在Tasklet
中使用paymentStepExecttionListener
。
还有一件事是StepExecutionListener
只在scope=“step”中定义的bean中工作
所以我应该使用
//您只能在//scope=“step”中定义的bean中访问stepExecutionContext。
@Bean
@StepScope
public PaymentStepExecutionListener paymentStepExecutionListener() {
return new PaymentStepExecutionListener();
}
现在情况很好。
然而,我正在努力配置使用@Bean在步骤创建确切的配置。
与Java配置中的XML代码片段类似的内容如下:
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<Payment, Payment>chunk(100000)
.reader(paymentDataReader())
.writer(paymentDataWriter())
.listener(paymentingStepExecutionListener())
.build();
}
@Bean
public Job paymentDataBatchJob() {
return jobBuilderFactory.get("paymentDataBatchJob")
.start(step1())
.next(sendpaymentingBatchFiles())
.build();
}
第2步。根据在步骤1中创建的对象列表中有多少项创建步骤列表。 第三步。尝试执行步骤2中创建的步骤列表中的步骤。 下面在executeDynamicStepsTasklet()中执行x个步骤。虽然代码运行时没有任何错误,但它似乎没有做任何事情。我在那个方法中的内容看起来正确吗?
根据已接受的答案代码,对该代码的以下调整对我起作用: 我已经将这个问题更新到了一个可以正确循环的版本,但是由于应用程序将扩展,能够处理并行是很重要的,我仍然不知道如何在运行时用javaconfig动态地做到这一点... 基于查询列表(HQL查询),我希望每个查询都有一个读取器-处理器-写入器。我当前的配置如下所示: 工单 处理机 作家 目前,该过程对于单个查询来说工作得很好。然而,我实际上有一个查
给定一个使用分区的Spring批处理作业,是否可能有多个分区步骤? 例如: 在上述示例中,是否可以将另一个添加到(最好不需要为每个分区步骤提供分区器)?如果没有,是否有其他方法来配置多个步骤,这些步骤将针对每个分区逐个执行?
我需要避免在Spring批处理项目中两次处理同一个文件。因此,我需要将文件名作为作业参数。然而,我只在步骤1中知道文件名,在作业执行之前不知道。因此,在启动作业时,我无法将文件名作为作业参数传递。我的问题是,在知道文件名后,是否有其他方法在步骤1中传递作业参数?
我的Spring Batch配置有5个步骤,除了阅读器之外,所有步骤都是相同的。有没有一种方法可以把步骤的所有其他部分抽象成“父”步骤,这样我就不需要重复所有的事情?我知道这可以用XML完成,但是我不知道java的等价物。 以下是其中一个步骤: 以下是其中一位读者的定义:
我目前正在构建一个spring批处理应用程序,其中执行了几个步骤。除了一个,所有的步骤都是简单的tasklet(没有读取器或写入器),它们负责各种任务,如复制文件、发送请求、启动批处理(*.bat)文件等。 大多数步骤应该是串行执行的。在一个特定的步骤中,我希望启动X文件,这些文件最多可以有Y个实例。 null 如果:)我想我必须使用taskExecutor,下面我有一个示例,在这里我开始第一步(