• No results found

Intercepting Step Execution

4.4. Application Tier

4.4.1.7. Intercepting Step Execution

Just as with theJob, there are many events during the execution of aStepthat a user may need notification of.

For example, if writing out to a flat file that requires a footer, theItemWriter needs to be notified when the Stephas been completed, so that it can write the footer. This can be accomplished with one of many Step

scoped listeners.

4.4.1.7.1. StepExecutionListener

StepExecutionListener represents the most generic listener for Step execution. It allows for notification

before aStepis started, after it has completed, and if any errors are encountered during processing:

public interface StepExecutionListener extends StepListener { void beforeStep(StepExecution stepExecution);

ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e); ExitStatus afterStep(StepExecution stepExecution);

ExitStatusis the return type ofonErrorInStepandafterStepin order to allow listeners the chance to modify

the exit code that is returned upon completion of aStep. AStepExecutionListenercan be applied to any step

factory bean via the listeners property:

<bean id="simpleStep"

class="org.springframework.batch.core.step.item.SimpleStepFactoryBean" > <property name="transactionManager" ref="transactionManager" />

<property name="jobRepository" ref="jobRepository" /> <property name="itemReader" ref="itemReader" /> <property name="itemWriter" ref="itemWriter" /> <property name="commitInterval" value="10" /> <property name="listeners" ref="stepListener" /> </bean>

Because all listeners extend theStepListenerinterface, they all may be applied to factory beans in the same

way.

4.4.1.7.2. ChunkListener

A chunk is defined as the items processed within the scope of a transaction. Committing a transaction commits a 'chunk'. It may be useful to be nofied before and after a chunk has completed, in which case the

ChunkListenerinterface may be used:

public interface ChunkListener extends StepListener { void beforeChunk();

void afterChunk(); }

ThebeforeChunkmethod is called after the transaction is started, but beforereadis called on theItemReader.

Conversely,afterChunkis called after the last call towriteon theItemWriter, but before the chunk has been

committed.

4.4.1.7.3. ItemReadListener

When discussing skip logic above, it was mentioned that it may be beneficial to log out skipped records, so that they can be deal with later. In the case of read errors, this can be done with anItemReaderListener:

public interface ItemReadListener extends StepListener { void beforeRead();

void afterRead(Object item); void onReadError(Exception ex); }

ThebeforeReadmethod will be called before each call toreadon theItemReader. TheafterReadmethod will

be called after each successful call toread, and will be passed the item that was read. If there was an error

while reading, theonReadErrormethod will be called. The exception encounterd will be provided so that it can

be logged.

4.4.1.7.4. ItemWriteListener

Just as with the ItemReaderListener, the writing of an item can be 'listened' to:

public interface ItemWriteListener extends StepListener { void beforeWrite(Object item);

void afterWrite(Object item);

void onWriteError(Exception ex, Object item); }

ThebeforeWritemethod will be called beforewriteon the ItemWriter, and is handed the item that will be

written. TheafterWritemethod will be called after the item has been succesfully writen. If there was an error

while writing, the onWriteError method will be called. The exception encountered and the item that was

attempted to be written will be provided, so that they can be logged.

4.4.2. TaskletStep

ItemOriented processing is not the only way to process in aStep. What if aStepmust consist as a simple storec

procedure call? You could implement the call as anItemReaderand return null after the procedure finishes, but

it is a bit unnatural since there would need to be a no-op ItemWriter and lots of overhead for transaction

handling, listeners, etc. Spring Batch provides an implementation ofStepfor this scenario: TaskletStep. As

explained in Chapter 2, theTaskletis a simple interface that has one method,execute, which will be a called

once for the wholeStep.Tasklet implementors might call a stored procedure, a script, or a simple SQL upate

statement. Because there are less concerns, there are only two required dependencies for a TaskletStep: a Tasklet, and aJobRepository:

<bean id="taskletStep"

class="org.springframework.batch.core.step.tasklet.TaskletStep" /> <property name="tasklet" ref="tasklet" />

<property name="jobRepository" ref="repository" /> </bean>

4.4.2.1. TaskletAdapter

As with other adapters for the ItemWriter and ItemReader interfaces, the Tasklet interface contains an

implementation that allows for adapting itself to any pre-existing class:TaskletAdapter. An example where

this may be useful is an existing DAO that is used to upate a flag on a set of records. TheTaskletAdaptercan

be used to call this class without having to write an adapter for theTaskletinterface:

<bean id="deleteFilesInDir" parent="taskletStep"> <property name="tasklet">

<bean class="org.springframework.batch.core.step.tasklet.TaskletAdapter"> <property name="targetObject">

<bean class="org.mycompany.FooDao"> </property>

<property name="targetMethod" value-"updateFoo" /> </bean>

</property> </bean>

Related documents