設定 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
。JobRepository
的配置透過 Java 配置
處理。
前面的範例說明了一個包含三個 Step
實例的 Job
。與 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 定義來建立 step。有關宣告特定 step 詳細資訊的更多選項,請參閱關於 step 配置 的章節。XML 命名空間預設引用 id
為 jobRepository
的 repository,這是一個合理的預設值。但是,您可以明確地覆蓋此預設值
<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 時,一個關鍵問題涉及 Job
在重新啟動時的行為。如果特定 JobInstance
已存在 JobExecution
,則 Job
的啟動被視為「重新啟動」。理想情況下,所有 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
}
第一次嘗試為不可重新啟動的 job 建立 JobExecution
不會引起任何問題。但是,第二次嘗試會拋出 JobRestartException
。
攔截 Job 執行
在 Job
執行的過程中,可能需要收到其生命週期中各種事件的通知,以便可以執行自訂程式碼。SimpleJob
透過在適當的時間呼叫 JobListener
來實現這一點
public interface JobExecutionListener {
void beforeJob(JobExecution jobExecution);
void afterJob(JobExecution jobExecution);
}
您可以透過在 job 上設定 listeners,將 JobListeners
新增到 SimpleJob
。
-
Java
-
XML
以下範例示範如何在 Java job 定義中新增 listener 方法
@Bean
public Job footballJob(JobRepository jobRepository) {
return new JobBuilder("footballJob", jobRepository)
.listener(sampleListener())
...
.build();
}
以下範例示範如何在 XML job 定義中新增 listener 元素
<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
將其元素和屬性與父項的元素和屬性組合起來。
在以下範例中,baseJob
是一個抽象的 Job
定義,僅定義了 listeners 列表。Job
(job1
) 是一個具體的定義,它從 baseJob
繼承 listeners 列表,並將其與自己的 listeners 列表合併,以產生一個具有兩個 listeners 和一個 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
的任何子類別的 job 可以選擇性地宣告 job 參數在執行階段的驗證器。當您需要斷言 job 是使用其所有必要參數啟動時,這非常有用。有一個 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 定義。