配置 Job
Job 接口有多种实现。然而,这些实现被抽象在所提供的构建器(用于 Java 配置)或 XML 命名空间(用于基于 XML 的配置)之后。以下示例展示了 Java 和 XML 配置
-
Java
-
XML
@Bean
public Job footballJob(JobRepository jobRepository) {
return new JobBuilder("footballJob", jobRepository)
.start(playerLoad())
.next(gameLoad())
.next(playerSummarization())
.build();
}
一个 Job(通常,其中包含的任何 Step)需要一个 JobRepository。
前面的例子展示了一个由三个 Step 实例组成的 Job。与作业相关的构建器还可以包含其他元素,这些元素有助于并行化(Split)、声明式流控制(Decision)和流定义的外部化(Flow)。
Job 接口有多种实现。然而,命名空间抽象了配置中的差异。它只有三个必需的依赖项:名称、JobRepository 和 Step 实例列表。以下示例创建了一个 footballJob
<job id="footballJob">
<step id="playerload" parent="s1" next="gameLoad"/>
<step id="gameLoad" parent="s2" next="playerSummarization"/>
<step id="playerSummarization" parent="s3"/>
</job>
前面的示例使用父 bean 定义来创建步骤。有关声明特定步骤详情的更多选项,请参阅步骤配置部分。XML 命名空间默认引用一个 id 为 jobRepository 的仓库,这是一个合理的默认值。但是,您可以明确覆盖此默认值
<job id="footballJob" job-repository="specialRepository">
<step id="playerload" parent="s1" next="gameLoad"/>
<step id="gameLoad" parent="s3" next="playerSummarization"/>
<step id="playerSummarization" parent="s3"/>
</job>
除了步骤,作业配置还可以包含其他元素,这些元素有助于并行化 (<split>)、声明式流程控制 (<decision>) 和流程定义的外部化 (<flow/>)。
可重启性
执行批处理作业时的一个关键问题是 Job 在重新启动时的行为。如果特定 JobInstance 的 JobExecution 已经存在,则启动 Job 被视为“重新启动”。理想情况下,所有作业都应该能够从它们停止的地方开始,但在某些情况下这是不可能的。在这种情况下,完全由开发人员确保创建一个新的 JobInstance。然而,Spring Batch 提供了一些帮助。如果 Job 永远不应该重新启动,而应该始终作为新 JobInstance 的一部分运行,您可以将 restartable 属性设置为 false。
-
Java
-
XML
以下示例展示了如何在 Java 中将 restartable 字段设置为 false
@Bean
public Job footballJob(JobRepository jobRepository) {
return new JobBuilder("footballJob", jobRepository)
.preventRestart()
...
.build();
}
以下示例展示了如何在 XML 中将 restartable 字段设置为 false
<job id="footballJob" restartable="false">
...
</job>
换句话说,将 restartable 设置为 false 意味着“此 Job 不支持再次启动”。重新启动不可重启的 Job 会抛出 JobRestartException。以下 Junit 代码会导致此异常被抛出
Job job = new SimpleJob();
job.setRestartable(false);
JobParameters jobParameters = new JobParameters();
JobExecution firstExecution = jobRepository.createJobExecution(job, jobParameters);
jobRepository.saveOrUpdate(firstExecution);
try {
jobRepository.createJobExecution(job, jobParameters);
fail();
}
catch (JobRestartException e) {
// expected
}
第一次为不可重启的作业创建 JobExecution 没有问题。但是,第二次尝试会抛出 JobRestartException。
拦截作业执行
在 Job 执行过程中,能够收到其生命周期中各种事件的通知,以便运行自定义代码可能很有用。SimpleJob 通过在适当的时间调用 JobListener 来实现这一点
public interface JobExecutionListener {
void beforeJob(JobExecution jobExecution);
void afterJob(JobExecution jobExecution);
}
您可以通过在作业上设置监听器来向 SimpleJob 添加 JobListeners。
-
Java
-
XML
以下示例展示了如何向 Java 作业定义添加监听器方法
@Bean
public Job footballJob(JobRepository jobRepository) {
return new JobBuilder("footballJob", jobRepository)
.listener(sampleListener())
...
.build();
}
以下示例展示了如何向 XML 作业定义添加监听器元素
<job id="footballJob">
<step id="playerload" parent="s1" next="gameLoad"/>
<step id="gameLoad" parent="s2" next="playerSummarization"/>
<step id="playerSummarization" parent="s3"/>
<listeners>
<listener ref="sampleListener"/>
</listeners>
</job>
请注意,无论 Job 成功或失败,都会调用 afterJob 方法。如果您需要确定成功或失败,可以从 JobExecution 中获取该信息
public void afterJob(JobExecution jobExecution){
if (jobExecution.getStatus() == BatchStatus.COMPLETED ) {
//job success
}
else if (jobExecution.getStatus() == BatchStatus.FAILED) {
//job failure
}
}
与此接口对应的注解有
-
@BeforeJob -
@AfterJob
从父作业继承
如果一组作业共享相似但不完全相同的配置,定义一个“父”Job,具体 Job 实例可以从其中继承属性,可能会有所帮助。类似于 Java 中的类继承,“子”Job 将其元素和属性与父级的元素和属性合并。
在以下示例中,baseJob 是一个抽象的 Job 定义,它只定义了一个监听器列表。Job(job1)是一个具体的定义,它从 baseJob 继承了监听器列表,并将其与自己的监听器列表合并,以生成一个具有两个监听器和一个 Step(step1)的 Job。
<job id="baseJob" abstract="true">
<listeners>
<listener ref="listenerOne"/>
</listeners>
</job>
<job id="job1" parent="baseJob">
<step id="step1" parent="standaloneStep"/>
<listeners merge="true">
<listener ref="listenerTwo"/>
</listeners>
</job>
有关更多详细信息,请参阅从父步骤继承部分。
JobParametersValidator
在 XML 命名空间中声明的或使用 AbstractJob 的任何子类的作业都可以选择在运行时声明作业参数的验证器。当您需要断言作业以所有必需参数启动时,这非常有用。有一个 DefaultJobParametersValidator,您可以使用它来限制简单必需参数和可选参数的组合。对于更复杂的约束,您可以自己实现接口。
-
Java
-
XML
通过 Java 构建器支持验证器的配置
@Bean
public Job job1(JobRepository jobRepository) {
return new JobBuilder("job1", jobRepository)
.validator(parametersValidator())
...
.build();
}
通过 XML 命名空间,通过 job 的子元素支持验证器的配置,如以下示例所示
<job id="job1" parent="baseJob3">
<step id="step1" parent="standaloneStep"/>
<validator ref="parametersValidator"/>
</job>
您可以将验证器指定为引用(如前所示)或作为 beans 命名空间中的嵌套 bean 定义。