和傳統的批處理(Batch Processing)相比,Spring Batch雖然有很大的不同,但是歸根結底,都是順序地執行一些列任務。你用Spring Batch可以讀取一個TXT文件的內容,然后將處理之后的數據放到數據庫里,反之亦然。
Spring Batch任務處理的核心組件有Job、Step、Tasklet、JobLuncher和JobRepository等。其中,Job即每次批處理時需要完成的工作,一個Job可以包含多個Step,Step可以順序執行,也可以通過配置分支性執行。Tasklet為相對獨立的一個任務步驟,比如清空數據庫、啟動Web服務器等。JobLuncher用來運行一個Job,而JobRepository則用於完成Spring Batch本身的數據庫訪問,我們只需要配置好JobRepository就行了,至於數據庫訪問操作則又框架自動完成。
一般的批處理都是通過任務計划工具(Scheduler)來自動啟動,比如Linux下的corn。對於Spring Batch,我們可以用Quartz和ControlM等任務計划工具來進行定時啟動。
在用JobLuncher啟動一個Job時,我們需要提供JobParameters。JobParameters的作用是一方面可以向Job提供一些參數,一方面可以用來標定Job的唯一性。比如,對於前者,你可以將日期參數傳給Job,然后在Job中使用該日期從數據庫中查詢當天的數據記錄;而對於后者,如果先后兩次執行同一個Job時傳入的參數一樣,那么在第二次執行時,Spring Batch會抱怨“已經有一個相同的Job實例存在”,然后終止第二次Job的執行,所以在用JobLuncher執行Job時,我們需要提供不同的JobParameter來保證每次Job執行的唯一性。當然,JobParameters中可以包含多個參數,根據你自己的需要,有些參數可以在前后執行Job時保持一致,但是所有的JobParameters不能夠全部相同。下面代碼演示了如何執行一個Job:
HashMap<String, JobParameter> parameters = new HashMap<String, JobParameter>(); parameters.put("myParameter", new JobParameter("today")); JobParameters jobParameters = new JobParameters(parameters); jobLauncher.run(myJob, jobParameters);
對於通常的一些Step,我們都需要先讀入一些數據,再寫出一些數據。Spring Batch為我們提供了ItemReader和ItemWriter,配置如下:
<job id="myJob" xmlns="http://www.springframework.org/schema/batch">
<step id="simpleTaskletStep" next="simplePrintStep">
<tasklet>
<chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</tasklet>
</step>
</job>
以上代碼配置了一個名為myJob的Job,該Job中包含了一個Step,在該Step的tasklet中配置了一個itemReader和itemWriter。
ItemReader和ItemWriter均為均為接口,我們需要定義自己的reader和writer來分別實現這兩個接口。當然,也可以使用Spring Batch現成提供的,比如JdbcCurcorItemReader。
一個Tasklet中的ItemReader和ItemWriter協同工作,基本原理是:ItemReader中read方法會被框架循環調用,直到read方法返回null為止。read返回的對象會自動的傳給ItemWriter的write方法。ItemReader的read方法返回的一般為一個我們自己定義領域對象,而你會發現ItemWriter的write方法接受的並不是單個對象,而是一個List,這便和以上配置中的commit-interval有關系了。
舉個例子,對已以上配置,commit-interval="2",表示框架首先會執行兩次ItemReader的read方法,再將這兩次分別返回的對象放到一個List里面,最后將該List傳給ItemWriter。然后又重新執行read方法兩次,將得到的List傳給write方法。這樣重復執行,知道read方法返回為null為止。
關於Spring Batch的例子,可以查看筆者的Github。