針對(duì)我們的實(shí)踐中,我們可以使用 Tasklet 來執(zhí)行一個(gè) FTP 的任務(wù)。
創(chuàng)新互聯(lián)建站是一家專注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作和香港機(jī)房服務(wù)器托管的網(wǎng)絡(luò)公司,有著豐富的建站經(jīng)驗(yàn)和案例。
將我們產(chǎn)生的中間文件上傳到不同的 FTP 服務(wù)器上,你可以在實(shí)現(xiàn)中指定不同的服務(wù)器配置參數(shù),這樣更加有利于代碼的重用。
為了能夠創(chuàng)建一個(gè) TaskletStep
,Bean 需要傳遞一個(gè) tasklet 方法到構(gòu)造器(builder),這個(gè) tasklet 方法需要實(shí)現(xiàn) Tasklet 接口。
當(dāng)你構(gòu)建 TaskletStep 的時(shí)候不要調(diào)用 chunk
。
下面的示例代碼顯示了一個(gè)在 Step build 中構(gòu)建一個(gè)簡(jiǎn)單的 tasklet。
@Bean public Step step1() { return this .stepBuilderFactory.get( "step1" ) .tasklet(myTasklet()) .build(); } |
如果你的 tasklet
實(shí)現(xiàn)了 StepListener
接口的話,TaskletStep
將會(huì)自動(dòng)將 tasklet
注冊(cè)成為一個(gè) StepListener
。
與 ItemReader
和 ItemWriter
接口的 adapters
一樣。Tasklet
接口包含的實(shí)現(xiàn)也允許能夠通過已經(jīng)存在的類使用 TaskletAdapter
來將自己進(jìn)行注冊(cè)。
例如,你希望使用一個(gè)已經(jīng)存在的 DAO 來更新記錄集上的標(biāo)記的時(shí)候,你可以使用 TaskletAdapter
來進(jìn)行實(shí)現(xiàn)。
使用 TaskletAdapter
能夠讓你的 DAO 可以被 Spring Batch 的 TaskletStep
調(diào)用而不需要讓你的 DAO 都實(shí)現(xiàn) Tasklet 的接口。
如下面的示例代碼:
@Bean public MethodInvokingTaskletAdapter myTasklet() { MethodInvokingTaskletAdapter adapter = new MethodInvokingTaskletAdapter(); adapter.setTargetObject(fooDao()); adapter.setTargetMethod( "updateFoo" ); return adapter; } |
在主批量作業(yè)開始之前,可能需要很多其他的批量作業(yè)必須完成,這樣以便于主批量作業(yè)能夠獲得必要的資源和在完成后釋放資源或者進(jìn)行清理。
例如我們遇到下面的使用場(chǎng)景,一個(gè)批量作業(yè)需要大量的對(duì)文件進(jìn)行交互和使用,通常來說需要在文件被上傳到其他服務(wù)器上后刪除本地產(chǎn)生的臨時(shí)文件。
下面的示例就是一個(gè) Tasklet 的實(shí)現(xiàn),這個(gè)Tasklet
的實(shí)現(xiàn)能夠完成上面的交互要求(文件來自 Spring Batch samples project 示例程序)。
public class FileDeletingTasklet implements Tasklet, InitializingBean { private Resource directory; public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { File dir = directory.getFile(); Assert.state(dir.isDirectory()); File[] files = dir.listFiles(); for ( int i = 0 ; i < files.length; i++) { boolean deleted = files[i].delete(); if (!deleted) { throw new UnexpectedJobExecutionException( "Could not delete file " + files[i].getPath()); } } return RepeatStatus.FINISHED; } public void setDirectoryResource(Resource directory) { this .directory = directory; } public void afterPropertiesSet() throws Exception { Assert.notNull(directory, "directory must be set" ); } } |
Tasklet
處理程序?qū)崿F(xiàn)了將給定目錄中的所有文件進(jìn)行刪除。我們應(yīng)該通知 execute
方法,這個(gè) Tasklet 應(yīng)該只被執(zhí)行一次。
所有相關(guān)執(zhí)行的操作需要在 Step
中進(jìn)行設(shè)置,請(qǐng)參考下面有關(guān)這個(gè) Tasklet
的設(shè)置:
Java 配置
@Bean public Job taskletJob() { return this .jobBuilderFactory.get( "taskletJob" ) .start(deleteFilesInDir()) .build(); } @Bean public Step deleteFilesInDir() { return this .stepBuilderFactory.get( "deleteFilesInDir" ) .tasklet(fileDeletingTasklet()) .build(); } @Bean public FileDeletingTasklet fileDeletingTasklet() { FileDeletingTasklet tasklet = new FileDeletingTasklet(); tasklet.setDirectoryResource( new FileSystemResource( "target/test-outputs/test-dir" )); return tasklet; } |