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

126 lines
11 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>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">&lt;job id="footballJob"&gt;
&lt;step id="playerload" parent="s1" next="gameLoad"/&gt;
&lt;step id="gameLoad" parent="s2" next="playerSummarization"/&gt;
&lt;step id="playerSummarization" parent="s3"/&gt;
&lt;/job&gt;</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">&lt;job id="footballJob" <span class="bold"><strong>job-repository="specialRepository"</strong></span>&gt;
&lt;step id="playerload" parent="s1" next="gameLoad"/&gt;
&lt;step id="gameLoad" parent="s3" next="playerSummarization"/&gt;
&lt;step id="playerSummarization" parent="s3"/&gt;
&lt;/job&gt;</pre><p>In addition to steps a job configuration can contain other elements
that help with parallelisation (<code class="literal">&lt;split/&gt;</code>),
declarative flow control (<code class="literal">&lt;decision/&gt;</code>) and
externalization of flow definitions
(<code class="literal">&lt;flow/&gt;</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">&lt;job id="footballJob" <span class="bold"><strong>restartable="false"</strong></span>&gt;
...
&lt;/job&gt;</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">&lt;job id="footballJob"&gt;
&lt;step id="playerload" parent="s1" next="gameLoad"/&gt;
&lt;step id="gameLoad" parent="s2" next="playerSummarization"/&gt;
&lt;step id="playerSummarization" parent="s3"/&gt;
<span class="bold"><strong> &lt;listeners&gt;
&lt;listener ref="sampleListener"/&gt;
&lt;/listeners&gt;
</strong></span>&lt;/job&gt;</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">&lt;job id="baseJob" abstract="true"&gt;
&lt;listeners&gt;
&lt;listener ref="listenerOne"/&gt;
&lt;listeners&gt;
&lt;/job&gt;
&lt;job id="job1" parent="baseJob"&gt;
&lt;step id="step1" parent="standaloneStep"/&gt;
&lt;listeners merge="true"&gt;
&lt;listener ref="listenerTwo"/&gt;
&lt;listeners&gt;
&lt;/job&gt;</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">&lt;job id="job1" parent="baseJob3"&gt;
&lt;step id="step1" parent="standaloneStep"/&gt;
&lt;validator ref="paremetersValidator"/&gt;
&lt;/job&gt;</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>