Files
spring-batch/build/reference-epub-work/ch05s02.xhtml
Michael Minella 75ab909314 update
2017-03-23 10:18:33 -05:00

86 lines
6.7 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:pls="http://www.w3.org/2005/01/pronunciation-lexicon" xmlns:ssml="http://www.w3.org/2001/10/synthesis" xmlns:svg="http://www.w3.org/2000/svg"><head><title>TaskletStep</title><link rel="stylesheet" type="text/css" href="docbook-epub.css"/><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"/><link rel="prev" href="ch05.xhtml" title="Chapter 5. Configuring a Step"/><link rel="next" href="ch05s03.xhtml" title="Controlling Step Flow"/></head><body><header/><section class="section" title="TaskletStep" epub:type="subchapter" id="taskletStep"><div class="titlepage"><div><div><h2 class="title" style="clear: both">TaskletStep</h2></div></div></div><p>Chunk-oriented processing is not the only way to process in a
<code class="classname">Step</code>. What if a <code class="classname">Step</code> must
consist as a simple stored procedure call? You could implement the call as
an <code class="classname">ItemReader</code> and return null after the procedure
finishes, but it is a bit unnatural since there would need to be a no-op
<code class="classname">ItemWriter</code>. Spring Batch provides the
<code class="classname">TaskletStep</code> for this scenario.</p><p>The <code class="classname">Tasklet</code> is a simple interface that has
one method, <code class="methodname">execute</code>, which will be a called
repeatedly by the <code class="classname">TaskletStep</code> until it either
returns <code class="literal">RepeatStatus.FINISHED</code> or throws an exception to
signal a failure. Each call to the <code class="classname">Tasklet</code> is
wrapped in a transaction. <code class="classname">Tasklet</code> implementors
might call a stored procedure, a script, or a simple SQL update statement.
To create a <code class="classname">TaskletStep</code>, the 'ref' attribute of the
&lt;tasklet/&gt; element should reference a bean defining a
<code class="classname">Tasklet</code> object; no &lt;chunk/&gt; element should be
used within the &lt;tasklet/&gt;:</p><pre class="programlisting">&lt;step id="step1"&gt;
&lt;tasklet ref="myTasklet"/&gt;
&lt;/step&gt;</pre><div class="note" title="Note" epub:type="notice"><table style="border: 0; "><tr><td style="text-align: center; vertical-align: top; width: 25; " rowspan="2"><img alt="[Note]" src="images/note.png"/></td><th style="text-align: left; ">Note</th></tr><tr><td style="text-align: left; vertical-align: top; "><p><code class="classname">TaskletStep</code> will automatically register the
tasklet as <code class="classname">StepListener</code> if it implements this
interface</p></td></tr></table></div><section class="section" title="TaskletAdapter" epub:type="division" id="taskletAdapter"><div class="titlepage"><div><div><h3 class="title">TaskletAdapter</h3></div></div></div><p>As with other adapters for the <code class="classname">ItemReader</code>
and <code class="classname">ItemWriter</code> interfaces, the
<code class="classname">Tasklet</code> interface contains an implementation that
allows for adapting itself to any pre-existing class:
<code class="classname">TaskletAdapter</code>. An example where this may be
useful is an existing DAO that is used to update a flag on a set of
records. The <code class="classname">TaskletAdapter</code> can be used to call
this class without having to write an adapter for the
<code class="classname">Tasklet</code> interface:</p><pre class="programlisting">&lt;bean id="myTasklet" class="o.s.b.core.step.tasklet.MethodInvokingTaskletAdapter"&gt;
&lt;property name="targetObject"&gt;
&lt;bean class="org.mycompany.FooDao"/&gt;
&lt;/property&gt;
&lt;property name="targetMethod" value="updateFoo" /&gt;
&lt;/bean&gt;</pre></section><section class="section" title="Example Tasklet Implementation" epub:type="division" id="exampleTaskletImplementation"><div class="titlepage"><div><div><h3 class="title">Example Tasklet Implementation</h3></div></div></div><p>Many batch jobs contain steps that must be done before the main
processing begins in order to set up various resources or after
processing has completed to cleanup those resources. In the case of a
job that works heavily with files, it is often necessary to delete
certain files locally after they have been uploaded successfully to
another location. The example below taken from the Spring Batch samples
project, is a <code class="classname">Tasklet</code> implementation with just
such a responsibility:</p><pre class="programlisting">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 &lt; 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");
}
}</pre><p>The above <code class="classname">Tasklet</code> implementation will
delete all files within a given directory. It should be noted that the
<code class="methodname">execute</code> method will only be called once. All
that is left is to reference the <code class="classname">Tasklet</code> from the
<code class="classname">Step</code>:</p><pre class="programlisting">&lt;job id="taskletJob"&gt;
&lt;step id="deleteFilesInDir"&gt;
&lt;tasklet ref="fileDeletingTasklet"/&gt;
&lt;/step&gt;
&lt;/job&gt;
&lt;beans:bean id="fileDeletingTasklet"
class="org.springframework.batch.sample.tasklet.FileDeletingTasklet"&gt;
&lt;beans:property name="directoryResource"&gt;
&lt;beans:bean id="directory"
class="org.springframework.core.io.FileSystemResource"&gt;
&lt;beans:constructor-arg value="target/test-outputs/test-dir" /&gt;
&lt;/beans:bean&gt;
&lt;/beans:property&gt;
&lt;/beans:bean&gt;</pre></section></section><footer/></body></html>