|
当前版本仍在开发中,尚不被视为稳定版本。最新稳定版请使用 Spring Batch 文档 6.0.2! |
配置 Job
Job 接口有多种实现。不过,这些实现的差异已经被
构建器 API(用于 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 接口同样存在多种实现,
但 XML 命名空间已经屏蔽了它们在配置层面的差异。它只需要三个必要依赖:
名称、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 定义来创建各个步骤。
如果你希望以内联方式声明具体 step 细节并查看更多可选项,可参见
Step 配置一节。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>
除 step 之外,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 执行
在 Job 的执行过程中,能够在其生命周期的不同事件点收到通知通常会很有用,
这样就可以运行一些自定义代码。SimpleJob 会在合适的时机调用
JobListener 来实现这一点:
public interface JobExecutionListener {
void beforeJob(JobExecution jobExecution);
void afterJob(JobExecution jobExecution);
}
你可以通过为作业设置监听器,将 JobListener 添加到 SimpleJob 中。
-
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 的配置彼此相似但又不完全相同,那么定义一个“父”
Job 并让具体的 Job 实例从中继承属性,会很有帮助。
这与 Java 中的类继承类似,“子” Job 会把自身的元素和属性与父 Job 的内容组合起来。
在下面的示例中,baseJob 是一个抽象 Job 定义,
其中只定义了一组监听器。job1 是一个具体的 Job 定义,
它从 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>
更多细节可参见 从父 Step 继承一节。
JobParametersValidator
通过 XML 命名空间声明的作业,或任何使用 AbstractJob 子类的作业,
都可以选择在运行时为作业参数声明一个校验器。这在你需要确保作业启动时带齐所有必填参数时非常有用。
Spring Batch 提供了一个 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 定义的方式来指定它。