TaskletStep

面向塊處理並不是在 Step 中處理的唯一方式。如果一個 Step 必須包含一個儲存過程呼叫呢?你可以將呼叫實現為一個 ItemReader 並在過程完成後返回 null。然而,這樣做有點不自然,因為需要一個無操作的 ItemWriter。Spring Batch 為這種情況提供了 TaskletStep

Tasklet 介面有一個方法 executeTaskletStep 會重複呼叫此方法,直到它返回 RepeatStatus.FINISHED 或丟擲異常表示失敗。對 Tasklet 的每次呼叫都包裹在一個事務中。Tasklet 的實現者可以呼叫儲存過程、指令碼或 SQL 更新語句。

  • Java

  • XML

要在 Java 中建立 TaskletStep,傳遞給構建器的 tasklet 方法的 bean 應該實現 Tasklet 介面。構建 TaskletStep 時不應呼叫 chunk 方法。以下示例展示了一個簡單的 tasklet

@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("step1", jobRepository)
    			.tasklet(myTasklet(), transactionManager)
    			.build();
}

要在 XML 中建立 TaskletStep<tasklet/> 元素的 ref 屬性應引用定義 Tasklet 物件的 bean。<tasklet/> 中不應使用 <chunk/> 元素。以下示例展示了一個簡單的 tasklet

<step id="step1">
    <tasklet ref="myTasklet"/>
</step>
如果它實現了 StepListener 介面,TaskletStep 會自動將 tasklet 註冊為 StepListener

TaskletAdapter

與其他 ItemReaderItemWriter 介面的介面卡一樣,Tasklet 介面包含一個實現,允許其自身適應任何預先存在的類:TaskletAdapter。一個有用的示例是,一個現有的 DAO 用於更新一組記錄上的標誌。你可以使用 TaskletAdapter 呼叫此類的同時,而無需為 Tasklet 介面編寫介面卡。

  • Java

  • XML

以下示例展示瞭如何在 Java 中定義 TaskletAdapter

Java 配置
@Bean
public MethodInvokingTaskletAdapter myTasklet() {
	MethodInvokingTaskletAdapter adapter = new MethodInvokingTaskletAdapter();

	adapter.setTargetObject(fooDao());
	adapter.setTargetMethod("updateFoo");

	return adapter;
}

以下示例展示瞭如何在 XML 中定義 TaskletAdapter

XML 配置
<bean id="myTasklet" class="o.s.b.core.step.tasklet.MethodInvokingTaskletAdapter">
    <property name="targetObject">
        <bean class="org.mycompany.FooDao"/>
    </property>
    <property name="targetMethod" value="updateFoo" />
</bean>

Tasklet 實現示例

許多批處理作業包含一些必須在主處理開始前完成的步驟,以設定各種資源,或者在處理完成後清理這些資源。對於大量處理檔案的作業,通常在檔案成功上傳到另一個位置後,需要本地刪除某些檔案。以下示例(取自 Spring Batch 示例專案)是一個具有此職責的 Tasklet 實現

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(), "The resource must be a directory");

        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.state(directory != null, "Directory must be set");
    }
}

上述 tasklet 實現刪除了給定目錄中的所有檔案。需要注意的是,execute 方法只調用一次。剩下的就是從 step 中引用 tasklet

  • Java

  • XML

以下示例展示瞭如何在 Java 中從 step 引用 tasklet

Java 配置
@Bean
public Job taskletJob(JobRepository jobRepository, Step deleteFilesInDir) {
	return new JobBuilder("taskletJob", jobRepository)
				.start(deleteFilesInDir)
				.build();
}

@Bean
public Step deleteFilesInDir(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
	return new StepBuilder("deleteFilesInDir", jobRepository)
				.tasklet(fileDeletingTasklet(), transactionManager)
				.build();
}

@Bean
public FileDeletingTasklet fileDeletingTasklet() {
	FileDeletingTasklet tasklet = new FileDeletingTasklet();

	tasklet.setDirectoryResource(new FileSystemResource("target/test-outputs/test-dir"));

	return tasklet;
}

以下示例展示瞭如何在 XML 中從 step 引用 tasklet

XML 配置
<job id="taskletJob">
    <step id="deleteFilesInDir">
       <tasklet ref="fileDeletingTasklet"/>
    </step>
</job>

<beans:bean id="fileDeletingTasklet"
            class="org.springframework.batch.samples.tasklet.FileDeletingTasklet">
    <beans:property name="directoryResource">
        <beans:bean id="directory"
                    class="org.springframework.core.io.FileSystemResource">
            <beans:constructor-arg value="target/test-outputs/test-dir" />
        </beans:bean>
    </beans:property>
</beans:bean>
© . This site is unofficial and not affiliated with VMware.