內容來自《Spring Batch 批處理框架》,作者:劉相。
我只是個搬運工。
一、Spring Batch提供了獨立的標簽用來頂一個Job配置,分別是job、step、tasklet、chunk等。共有6個外層標簽使用,如下:
<batch:job id=""></batch:job><batch:flow id=""></batch:flow> <batch:job-listener></batch:job-listener> <batch:job-repository/> <batch:step id=""></batch:step> <batch:step-listener></batch:step-listener>
二、Job配置的標簽和屬性介紹
1.job標簽共有6個屬性,分別是:
<batch:job id="" job-repository="" incrementer="" restartable="" parent="" abstract="true"></batch:job>
id:Job名稱,作業的唯一標識。在整個跑批程序運行上下文中不允許重復。
job-repository:指定作業倉庫。定義該Job運行期間使用的Job倉庫,默認使用名字為jobRepository的Bean。
incrementer:作業參數遞增器。只有在org.springframework.batch.core.launch.JobOperator 的 startNextInstance方法中使用。
restartable:作業是否可以重啟。默認是true,表示支持重啟。當設置為true時,只有當JobInstance為FAILED狀態時才可以重啟。
parent:指定該作業的父類作業。指定當前Job的父Job,Job可以從其他Job繼承。通常在父Job中定義共有的屬性。
abstract:定義作業是否是抽象的,默認是true,抽象的,不能被實例化。
2.job標簽的子元素
<batch:job id="" job-repository="" incrementer="" restartable="" parent="" abstract="true"> <batch:step id="" allow-start-if-complete="" next="" parent=""></batch:step> <batch:split id="" next="" task-executor=""></batch:split> <batch:flow parent="" id=""></batch:flow> <batch:decision decider="" id=""></batch:decision> <batch:listeners></batch:listeners> <batch:validator ref=""></batch:validator> <batch:description></batch:description> </batch:job>
step:定義Job的作業步 。
split:定義並行作業步Step。
flow:引用獨立配置的作業步流程。
decision:定義作業步執行的條件判斷器,用於判斷后續執行的作業步。
listeners:定義作業Job執行時的攔截器。
validator:定義作業參數檢驗器。也就是JobParameters的驗證器。
description:描述該作業
3.Job攔截器
Spring Batch框架提供了自己的攔截器,可以在Job執行前后加入自定義的邏輯判斷,自定義攔截器需要實現接口:org.springframework.batch.core.JobExecutionListener。
JobExecutionListener源碼:
public interface JobExecutionListener { void beforeJob(JobExecution jobExecution); void afterJob(JobExecution jobExecution); }
自定義攔截器:
public class MyListener implements JobExecutionListener { private static final Logger LOGGER = LoggerFactory.getLogger(MyListener.class); @Override public void beforeJob(JobExecution jobExecution) { String jobName = jobExecution.getJobParameters().getString("jobName"); LOGGER.info(" -- > beforeJob 攔截的job名稱:[{}]", jobName); } @Override public void afterJob(JobExecution jobExecution) { long instanceId = jobExecution.getJobInstance().getInstanceId(); LOGGER.info(" -- > afterJob 攔截的job實例ID:[{}]", instanceId); } }
Job配置攔截器:
<bean id="myListener" class="com.jason.batch.job.listeners.MyListener"></bean> <batch:job id="firstJob" job-repository="jobRepository"> <!-- 省略其余步驟 --> <batch:listeners> <batch:listener ref="myListener"></batch:listener> </batch:listeners> </batch:job>
需要注意的是:如果攔截器方法出現異常,會導致Job執行的狀態為“FAILED”,所以我們在設置攔截器的時候要注意異常的處理。
在配置文件中也可以配置多個攔截器,多個攔截器的執行順序按照配置的順序執行。
<batch:job id="firstJob" job-repository="jobRepository"> <!-- 省略其余步驟 --> <!-- 多個攔截器配置 --> <batch:listeners> <batch:listener ref="listener_01"></batch:listener> <batch:listener ref="listener_02"></batch:listener> <batch:listener ref="listener_03"></batch:listener> </batch:listeners> </batch:job>
則上面三個攔截器的執行順序是:
1.調用listener_01攔截器的before方法。
2.調用listener_02攔截器的before方法。
3.調用listener_03攔截器的before方法。
4.調用listener_03攔截器的after方法。
5.調用listener_02攔截器的after方法。
6.調用listener_01攔截器的after方法。
Spring Batch 中不僅可以實現接口設置攔截器,也可以使用注解的方式。這兩種方式的配置方法都是一樣的。
@BeforeJob:聲明作業執行前的操作
@AfterJob:聲明作業執行后的操作
4.Job Parameters校驗
Spring Batch框架提供了參數校驗的功能。我們可以實現接口org.springframework.batch.core.JobParametersValidator就可以自定義參數校驗器,也可以使用框架提供的實現類CompositeJobParametersValidator和DefaultJobParametersValidator分別完成不同的功能。
CompositeJobParametersValidator:參數校驗組合模式,支持一組參數校驗。
DefaultJobParametersValidator:參數校驗默認實現,支持必須輸入的參數和非必須輸入的參數。
<!-- 驗證必輸參數jobName和非必輸參數path、jobDay --> <bean id="myValidator" class="org.springframework.batch.core.job.DefaultJobParametersValidator"> <property name="requiredKeys"> <set> <value>jobName</value> </set> </property> <property name="optionalKeys"> <set> <value>path</value> <value>jobDay</value> </set> </property> </bean> <batch:job id="firstJob" job-repository="jobRepository"> <!-- 省略其余步驟 --> <batch:validator ref="myValidator"></batch:validator> </batch:job>
接口DefaultJobParametersValidator的源碼:
public class DefaultJobParametersValidator implements JobParametersValidator, InitializingBean { private Collection<String> requiredKeys; private Collection<String> optionalKeys; // 其余省略 }
5.Job 抽象與繼承
Spring Batch框架支持抽象job的定義和Job的繼承特性,抽象Job和java中的抽象類相似。抽象的Job不能被實例化,直接調用抽象的Job會報錯。定義Job是將abstract設置為true即為抽象Job。
<batch:job id="baseJob" abstract="true"> <batch:listeners> <batch:listener ref="baseListeners"></batch:listener> </batch:listeners> </batch:job>
通過parent屬性可以指定當前Job的父Job,子Job繼承父Job可以獲得父類中所有屬性和能力,可以多個Job繼承同一個抽象父Job。
<batch:job id="firstJob" parent="baseJob"> <!-- 省略其余步驟 --> <batch:listeners merge="true"> <batch:listener ref="myListener"></batch:listener> </batch:listeners> </batch:job>
上面firstJob繼承了baseJob父類,攔截器merge為true表示firstJob具有baseListeners和myListener兩個攔截器的功能,如果merge為false,則子類的攔截器會覆蓋掉父類Job中攔截器的功能。
三、Job的高級特性
1.scope
scope用來聲明IOC容器中對象的存活周期,具體見:https://www.cnblogs.com/whx20100101/p/9807252.html
Step scope 是Spring Batch 框架提供的自定義的Scope,將Bean的scope=“step”,表示該bean在Step開始的時候初始化,在Step結束的時候銷毀bean,
在Spring Batch框架中,step scope會被自動注冊到Spring的上下文中,如果沒有使用Spring的配置文件,則需要顯示的聲明step scope。
<!-- 顯示的聲明StepScope --> <bean class="org.springframework.batch.core.scope.StepScope"/> <!-- 聲明bean的scope為step --> <bean id="fileReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"></bean>