和傳統的批處理(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。