126 lines
11 KiB
HTML
126 lines
11 KiB
HTML
<?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>Chapter 4. Configuring and Running a Job</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="ch03s09.xhtml" title="Batch Namespace"/><link rel="next" href="ch04s02.xhtml" title="Java Config"/></head><body><header/><section class="chapter" title="Chapter 4. Configuring and Running a Job" epub:type="chapter" id="configureJob"><div class="titlepage"><div><div><h1 class="title">Chapter 4. Configuring and Running a Job</h1></div></div></div><p>In the <a class="link" href="ch03.xhtml" title="Chapter 3. The Domain Language of Batch">domain section</a> , the overall
|
||
architecture design was discussed, using the following diagram as a
|
||
guide:</p><div style="text-align: center; " class="mediaobject"><img style="text-align: middle; " src="images/spring-batch-reference-model.png"/></div><p>While the <code class="classname">Job</code> object may seem like a simple
|
||
container for steps, there are many configuration options of which a
|
||
developers must be aware . Furthermore, there are many considerations for
|
||
how a <code class="classname">Job</code> will be run and how its meta-data will be
|
||
stored during that run. This chapter will explain the various configuration
|
||
options and runtime concerns of a <code class="classname">Job</code> .</p><section class="section" title="Configuring a Job" epub:type="subchapter" id="configuringAJob"><div class="titlepage"><div><div><h2 class="title" style="clear: both">Configuring a Job</h2></div></div></div><p>There are multiple implementations of the <a class="link" href="">
|
||
<code class="classname">Job</code> </a> interface, however, the namespace
|
||
abstracts away the differences in configuration. It has only three
|
||
required dependencies: a name, <code class="classname">JobRepository</code> , and
|
||
a list of <code class="classname">Step</code>s.</p><pre class="programlisting"><job id="footballJob">
|
||
<step id="playerload" parent="s1" next="gameLoad"/>
|
||
<step id="gameLoad" parent="s2" next="playerSummarization"/>
|
||
<step id="playerSummarization" parent="s3"/>
|
||
</job></pre><p>The examples here use a parent bean definition to create the steps;
|
||
see the section on <a class="link" href="ch05.xhtml" title="Chapter 5. Configuring a Step">step configuration</a>
|
||
for more options declaring specific step details inline. The XML namespace
|
||
defaults to referencing a repository with an id of 'jobRepository', which
|
||
is a sensible default. However, this can be overridden explicitly:</p><pre class="programlisting"><job id="footballJob" <span class="bold"><strong>job-repository="specialRepository"</strong></span>>
|
||
<step id="playerload" parent="s1" next="gameLoad"/>
|
||
<step id="gameLoad" parent="s3" next="playerSummarization"/>
|
||
<step id="playerSummarization" parent="s3"/>
|
||
</job></pre><p>In addition to steps a job configuration can contain other elements
|
||
that help with parallelisation (<code class="literal"><split/></code>),
|
||
declarative flow control (<code class="literal"><decision/></code>) and
|
||
externalization of flow definitions
|
||
(<code class="literal"><flow/></code>).</p><section class="section" title="Restartability" epub:type="division" id="restartability"><div class="titlepage"><div><div><h3 class="title">Restartability</h3></div></div></div><p>One key issue when executing a batch job concerns the behavior of
|
||
a <code class="classname">Job</code> when it is restarted. The launching of a
|
||
<code class="classname">Job</code> is considered to be a 'restart' if a
|
||
<code class="classname">JobExecution</code> already exists for the particular
|
||
<code class="classname">JobInstance</code>. Ideally, all jobs should be able to
|
||
start up where they left off, but there are scenarios where this is not
|
||
possible. <span class="bold"><strong>It is entirely up to the developer to
|
||
ensure that a new <code class="classname">JobInstance</code> is created in this
|
||
scenario</strong></span>. However, Spring Batch does provide some help. If a
|
||
<code class="classname">Job</code> should never be restarted, but should always
|
||
be run as part of a new <code class="classname">JobInstance</code>, then the
|
||
restartable property may be set to 'false':</p><pre class="programlisting"><job id="footballJob" <span class="bold"><strong>restartable="false"</strong></span>>
|
||
...
|
||
</job></pre><p>To phrase it another way, setting restartable to false means "this
|
||
Job does not support being started again". Restarting a Job that is not
|
||
restartable will cause a <code class="classname">JobRestartException</code> to
|
||
be thrown:</p><pre class="programlisting">Job job = new SimpleJob();
|
||
job.setRestartable(false);
|
||
|
||
JobParameters jobParameters = new JobParameters();
|
||
|
||
JobExecution firstExecution = jobRepository.createJobExecution(job, jobParameters);
|
||
jobRepository.saveOrUpdate(firstExecution);
|
||
|
||
try {
|
||
jobRepository.createJobExecution(job, jobParameters);
|
||
fail();
|
||
}
|
||
catch (JobRestartException e) {
|
||
// expected
|
||
}</pre><p>This snippet of JUnit code shows how attempting to create a
|
||
<code class="classname">JobExecution</code> the first time for a non restartable
|
||
<code class="classname">job</code> will cause no issues. However, the second
|
||
attempt will throw a <code class="classname">JobRestartException</code>.</p></section><section class="section" title="Intercepting Job Execution" epub:type="division" id="interceptingJobExecution"><div class="titlepage"><div><div><h3 class="title">Intercepting Job Execution</h3></div></div></div><p>During the course of the execution of a
|
||
<code class="classname">Job</code>, it may be useful to be notified of various
|
||
events in its lifecycle so that custom code may be executed. The
|
||
<code class="classname">SimpleJob</code> allows for this by calling a
|
||
<code class="classname">JobListener</code> at the appropriate time:</p><pre class="programlisting">public interface JobExecutionListener {
|
||
|
||
void beforeJob(JobExecution jobExecution);
|
||
|
||
void afterJob(JobExecution jobExecution);
|
||
|
||
}</pre><p><code class="classname">JobListener</code>s can be added to a
|
||
<code class="classname">SimpleJob</code> via the listeners element on the
|
||
job:</p><pre class="programlisting"><job id="footballJob">
|
||
<step id="playerload" parent="s1" next="gameLoad"/>
|
||
<step id="gameLoad" parent="s2" next="playerSummarization"/>
|
||
<step id="playerSummarization" parent="s3"/>
|
||
<span class="bold"><strong> <listeners>
|
||
<listener ref="sampleListener"/>
|
||
</listeners>
|
||
</strong></span></job></pre><p>It should be noted that <code class="methodname">afterJob</code> will be
|
||
called regardless of the success or failure of the
|
||
<code class="classname">Job</code>. If success or failure needs to be determined
|
||
it can be obtained from the <code class="classname">JobExecution</code>:</p><pre class="programlisting">public void afterJob(JobExecution jobExecution){
|
||
if( jobExecution.getStatus() == BatchStatus.COMPLETED ){
|
||
//job success
|
||
}
|
||
else if(jobExecution.getStatus() == BatchStatus.FAILED){
|
||
//job failure
|
||
}
|
||
}</pre><p>The annotations corresponding to this interface are:</p><div class="itemizedlist" epub:type="list"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem" epub:type="list-item"><p><code class="classname">@BeforeJob</code></p></li><li class="listitem" epub:type="list-item"><p><code class="classname">@AfterJob</code></p></li></ul></div></section><section class="section" title="Inheriting from a Parent Job" epub:type="division" id="inheritingFromAParentJob"><div class="titlepage"><div><div><h3 class="title">Inheriting from a Parent Job</h3></div></div></div><p>If a group of <code class="classname">Job</code>s share similar, but not
|
||
identical, configurations, then it may be helpful to define a "parent"
|
||
<code class="classname">Job</code> from which the concrete
|
||
<code class="classname">Job</code>s may inherit properties. Similar to class
|
||
inheritance in Java, the "child" <code class="classname">Job</code> will combine
|
||
its elements and attributes with the parent's.</p><p>In the following example, "baseJob" is an abstract
|
||
<code class="classname">Job</code> definition that defines only a list of
|
||
listeners. The <code class="classname">Job</code> "job1" is a concrete
|
||
definition that inherits the list of listeners from "baseJob" and merges
|
||
it with its own list of listeners to produce a
|
||
<code class="classname">Job</code> with two listeners and one
|
||
<code class="classname">Step</code>, "step1".</p><pre class="programlisting"><job id="baseJob" abstract="true">
|
||
<listeners>
|
||
<listener ref="listenerOne"/>
|
||
<listeners>
|
||
</job>
|
||
|
||
<job id="job1" parent="baseJob">
|
||
<step id="step1" parent="standaloneStep"/>
|
||
|
||
<listeners merge="true">
|
||
<listener ref="listenerTwo"/>
|
||
<listeners>
|
||
</job></pre><p>Please see the section on <a class="link" href="ch05.xhtml#InheritingFromParentStep" title="Inheriting from a Parent Step">Inheriting from a Parent Step</a>
|
||
for more detailed information.</p></section><section class="section" title="JobParametersValidator" epub:type="division" id="d5e953"><div class="titlepage"><div><div><h3 class="title">JobParametersValidator</h3></div></div></div><p>A job declared in the XML namespace or using any subclass of
|
||
AbstractJob can optionally declare a validator for the job parameters at
|
||
runtime. This is useful when for instance you need to assert that a job
|
||
is started with all its mandatory parameters. There is a
|
||
DefaultJobParametersValidator that can be used to constrain combinations
|
||
of simple mandatory and optional parameters, and for more complex
|
||
constraints you can implement the interface yourself. The configuration
|
||
of a validator is supported through the XML namespace through a child
|
||
element of the job, e.g:</p><pre class="programlisting"><job id="job1" parent="baseJob3">
|
||
<step id="step1" parent="standaloneStep"/>
|
||
<validator ref="paremetersValidator"/>
|
||
</job></pre><p>The validator can be specified as a reference (as above) or as a
|
||
nested bean definition in the beans namespace.</p></section></section></section><footer/></body></html> |