Chunk-Oriented Processing is not the only method of processing step.
Consider the following scenario, if you only need to call a stored procedure, you can ItemReader
achieve this call, then after the call is completed in the stored procedure that returns null. This design does not look so natural is not very beautiful, because you do not even need a batch designs to achieve ItemWriter. In view of this situation, Spring Batch provides TaskletStep option for you.
TaskletStep
It is a simple interface that only need to implement a method execute
, this method will be TaskletStep repeated calls until this method returns RepeatStatus.FINISHED
or throws an exception to indicate call failed.
Tasklet
Each call will be included in the transaction (Transaction). The realization Tasklet (implementors) can call a stored procedure, a script or a simple SQL update script.
For our practice, we can perform a task using FTP Tasklet.
Upload the intermediate files we generate to a different FTP server, you can specify a different server configuration parameters in implementation, so more conducive to code reuse.
To be able to create a TaskletStep
, Bean need to pass a tasklet constructor method (builder), this method requires tasklet Tasklet implement the interface.
When you build TaskletStep do not call chunk
.
The following sample code shows a simple build a tasklet in Step build in.
@Bean
public
Step step1() {
return
this
.stepBuilderFactory.get(
"step1"
)
.tasklet(myTasklet())
.build();
}
|
If you tasklet
implement the StepListener
interface, it TaskletStep
will automatically be tasklet
registered as a StepListener
.
TaskletAdapter
And ItemReader
and ItemWriter
interface adapters
the same. Tasklet
Interface is also included to allow through the use of already existing classes TaskletAdapter
to register their own will.
For example, you want to use DAO to update an existing time mark set on the record, you can use TaskletAdapter
to achieve.
Use TaskletAdapter
can make your DAO of Spring Batch can be TaskletStep
invoked without the need to implement Tasklet your DAO interface.
The following sample code:
@Bean
public
MethodInvokingTaskletAdapter myTasklet() {
MethodInvokingTaskletAdapter adapter =
new
MethodInvokingTaskletAdapter();
adapter.setTargetObject(fooDao());
adapter.setTargetMethod(
"updateFoo"
);
return
adapter;
}
|
Tasklet implement (Implementation) Example
Prior to the main batch job begins and may take many other batch job must be done so in order to master batch jobs to obtain the necessary resources and release resources after the completion or clean up.
For example, we encounter the following usage scenarios, a batch job requires a lot of interaction and the use of the file, in general, need to delete temporary files locally generated after the file is uploaded to other servers.
The following example is a Tasklet implementation, the Tasklet
implementation can be required to complete the above interaction (the file from Spring Batch samples project sample program).
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
Handler implements all the files in a given directory will be deleted. We should notice execute
method, this Tasklet should only be performed once.
All operations related to the executable must Step
be set, refer to the following on this Tasklet
setting:
Java configuration
@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;
}
|