TaskletStep
面向数据块的处理并不是在Step
.如果Step
必须包含存储过程调用?你可以
将调用实现为ItemReader
并在该过程完成后返回 null。
但是,这样做有点不自然,因为需要无作ItemWriter
.
Spring Batch 提供了TaskletStep
对于此方案。
这Tasklet
interface 只有一个方法execute
,称为
由TaskletStep
直到它返回RepeatStatus.FINISHED
或者投掷
表示失败的异常。每次调用Tasklet
包装在事务中。Tasklet
实现者可能会调用存储过程、脚本或 SQL 更新
陈述。
-
Java
-
XML
要创建TaskletStep
在 Java 中,传递给tasklet
构建器的方法
应实现Tasklet
接口。无需调用chunk
应在
构建TaskletStep
.下面的示例展示了一个简单的 tasklet:
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet(myTasklet(), transactionManager)
.build();
}
要创建TaskletStep
在 XML 中,ref
属性的<tasklet/>
元素应
引用一个定义Tasklet
对象。不<chunk/>
元素
在<tasklet/>
.下面的示例展示了一个简单的 tasklet:
<step id="step1">
<tasklet ref="myTasklet"/>
</step>
如果它实现了StepListener 接口TaskletStep 自动将 tasklet 注册为StepListener . |
TaskletAdapter
与ItemReader
和ItemWriter
interfaces 中,,Tasklet
interface 包含一个实现,该实现允许自身适应任何预先存在的
类:TaskletAdapter
.这可能有用的一个示例是现有的 DAO,它是
用于更新一组记录上的标志。您可以使用TaskletAdapter
调用此
类中,而不必为Tasklet
接口。
-
Java
-
XML
以下示例演示如何定义TaskletAdapter
在 Java 中:
@Bean
public MethodInvokingTaskletAdapter myTasklet() {
MethodInvokingTaskletAdapter adapter = new MethodInvokingTaskletAdapter();
adapter.setTargetObject(fooDao());
adapter.setTargetMethod("updateFoo");
return adapter;
}
以下示例演示如何定义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 samples 项目)是一个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
implementation 会删除给定目录中的所有文件。它
需要注意的是,execute
method 仅调用一次。剩下的就是
引用tasklet
从step
.
-
Java
-
XML
以下示例演示如何引用tasklet
从step
在 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;
}
以下示例演示如何引用tasklet
从step
在 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>