ItemReadListener, ItemWriteListener, and ItemProcessListener Example

In this post under Spring Batch, I will explain how to create listeners during

1) reading of an item
2) writing of an items
3) processing of an item

with an example.

We create listeners by implementing the three interfaces ItemReadListener, ItemWriteListener, and ItemProcessListener.

The class that implements ItemReadListener<T> interface must provide implementation for the below three methods
1) void beforeRead() –> called before an item is reading
2) void afterRead(T item) –> called after the item is read, where variable ‘item’ refers to the item read
3) void onReadError(Exception ex) –> called when an exception occurs reading an item.

The class that implements ItemWriteListener<S> interface must provide implementation for the below three methods
1) void beforeWrite(List items) –> called before the items are written
2) void afterWrite(List items) –> called after the items are written
3) void onWriteError(Exception exception, List items) –> called when an exception occurs writing the items

The class that implements ItemProcessListener<T, S> interface must provie implementation for the below three methods
1) void beforeProcess(T item) –> called before processing the item referenced by the variable ‘item’
2) void afterProcess(T item, S result) –> called after processing the item referenced by the variable ‘item’
3) void onProcessError(T item, Exception e) –> called when an exception occurs processing the item reference by the variable ‘item’

Below is an example of all the classes implementing the above interfaces

ItemReadListener


package package11;

import org.springframework.batch.core.ItemReadListener;

public class CustomItemReadListener implements ItemReadListener {
    @Override
    public void afterRead(Employee employee) {
        System.out.println("Read employee record: " + employee.getId());
    }

    @Override
    public void beforeRead() {
        System.out.println("Reading employee started");
    }

    @Override
    public void onReadError(Exception exception) {
        exception.printStackTrace();
    }
}

ItemWriteListener


package package11;

import java.util.List;

import org.springframework.batch.core.ItemWriteListener;

public class CustomItemWriteListener implements ItemWriteListener {
    @Override
    public void afterWrite(List employees) {
        System.out.println("Writing is completed");
    }

    @Override
    public void beforeWrite(List employees) {
        System.out.println("Writing is started");
    }

    @Override
    public void onWriteError(Exception exception, List employees) {
        exception.printStackTrace();
    }
}

ItemProcessListener


package package11;

import org.springframework.batch.core.ItemProcessListener;

public class CustomItemProcessListener implements ItemProcessListener {
    @Override
    public void afterProcess(Employee employee1, Employee employee2) {
        System.out.println("Item processing completed");
    }

    @Override
    public void beforeProcess(Employee employee) {
        System.out.println("Item processing started");
    }

    @Override
    public void onProcessError(Employee employee, Exception exception) {
        exception.printStackTrace();
    }
}

Next we integrate the listeners with the job using xml configuration as shown below


1   <bean id="customItemReadListener" class="package11.CustomItemReadListener"/>
2   <bean id="customItemWriteListener" class="package11.CustomItemWriteListener"/>
3   <bean id="customItemProcessListener" class="package11.CustomItemProcessListener"/>
4   
5   <batch:job id="importProductsJob">
6       <batch:step id="readWriteProducts">
7           <batch:tasklet>
8               <batch:chunk reader="reader" writer="writer" processor="employeeFilterItemProcessor" commit-interval="50"/>
9           </batch:tasklet>
10          <batch:listeners>
11              <batch:listener ref="customItemReadListener"/>
12              <batch:listener ref="customItemWriteListener"/>
13              <batch:listener ref="customItemProcessListener"/>
14          </batch:listeners>
15      </batch:step>
16  </batch:job>

In the above xml, at line 1, 2, and 3 we define bean customItemReadListener, customItemWriteListener, and customItemProcessListener.

And we integrate them to the job. Refer to line from 10 to 14.

Below is the complete main code

Main Code


package package11;

import java.util.Date;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Example11 {
    public static void main(String[] args) throws JobParametersInvalidException, JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobRestartException {
        ApplicationContext context = new ClassPathXmlApplicationContext("package11\\job.xml");
        JobLauncher jobLauncher = (JobLauncher)context.getBean("jobLauncher");
        JobParameters jobParameters = new JobParametersBuilder().addDate("date", new Date()).toJobParameters();
        Job job = (Job)context.getBean("importProductsJob");
        
        jobLauncher.run(job, jobParameters);
    }
}

Below is the complete xml configuration


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
    
    <bean id="employee" class="package11.Employee" scope="prototype"/>
    
    <bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="resource" value="file:FileInput.txt"/>
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <property name="lineTokenizer">
                    <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                        <property name="names" value="id,name,status,salary"/>
                    </bean>
                </property>
                <property name="fieldSetMapper">
                    <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="prototypeBeanName" value="employee"/>
                    </bean>
                </property>
            </bean>
        </property> 
    </bean>
    
    <bean id="writer" class="org.springframework.batch.item.file.FlatFileItemWriter">
        <property name="resource" value="file:FileOutput.txt"/>
        <property name="lineAggregator">
            <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                <property name="fieldExtractor">
                    <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <property name="names" value="id,name,status,salary"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    
    <bean id="employeeFilterItemProcessor" class="package11.EmployeeFilterItemProcessor" />
    
    <bean id="customItemReadListener" class="package11.CustomItemReadListener"/>
    <bean id="customItemWriteListener" class="package11.CustomItemWriteListener"/>
    <bean id="customItemProcessListener" class="package11.CustomItemProcessListener"/>
    
    <batch:job id="importProductsJob">
        <batch:step id="readWriteProducts">
            <batch:tasklet>
                <batch:chunk reader="reader" writer="writer" processor="employeeFilterItemProcessor" commit-interval="50"/>
            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="customItemReadListener"/>
                <batch:listener ref="customItemWriteListener"/>
                <batch:listener ref="customItemProcessListener"/>
            </batch:listeners>
        </batch:step>
    </batch:job>
    
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
    
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
    
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
</beans>

Output

Oct 13, 2018 12:53:39 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@61e4705b: startup date [Sat Oct 13 12:53:39 IST 2018]; root of context hierarchy
Oct 13, 2018 12:53:39 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [package11/job.xml]
Oct 13, 2018 12:53:40 PM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet
INFO: No TaskExecutor has been set, defaulting to synchronous executor.
Oct 13, 2018 12:53:40 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run
INFO: Job: [FlowJob: [name=importProductsJob]] launched with the following parameters: [{date=1539415420709}]
Oct 13, 2018 12:53:40 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [readWriteProducts]
Reading employee started
Read employee record: EMP_ID0
Reading employee started
Read employee record: EMP_ID1
Reading employee started
Read employee record: EMP_ID2
Reading employee started
Read employee record: EMP_ID3
Reading employee started
Read employee record: EMP_ID4
Reading employee started
Read employee record: EMP_ID5
Reading employee started
Read employee record: EMP_ID6
Reading employee started
Read employee record: EMP_ID7
Reading employee started
Read employee record: EMP_ID8
Reading employee started
Read employee record: EMP_ID9
Reading employee started
Read employee record: EMP_ID10
Reading employee started
Read employee record: EMP_ID11
Reading employee started
Read employee record: EMP_ID12
Reading employee started
Read employee record: EMP_ID13
Reading employee started
Read employee record: EMP_ID14
Reading employee started
Read employee record: EMP_ID15
Reading employee started
Read employee record: EMP_ID16
Reading employee started
Read employee record: EMP_ID17
Reading employee started
Read employee record: EMP_ID18
Reading employee started
Read employee record: EMP_ID19
Reading employee started
Read employee record: EMP_ID20
Reading employee started
Read employee record: EMP_ID21
Reading employee started
Read employee record: EMP_ID22
Reading employee started
Read employee record: EMP_ID23
Reading employee started
Read employee record: EMP_ID24
Reading employee started
Read employee record: EMP_ID25
Reading employee started
Read employee record: EMP_ID26
Reading employee started
Read employee record: EMP_ID27
Reading employee started
Read employee record: EMP_ID28
Reading employee started
Read employee record: EMP_ID29
Reading employee started
Read employee record: EMP_ID30
Reading employee started
Read employee record: EMP_ID31
Reading employee started
Read employee record: EMP_ID32
Reading employee started
Read employee record: EMP_ID33
Reading employee started
Read employee record: EMP_ID34
Reading employee started
Read employee record: EMP_ID35
Reading employee started
Read employee record: EMP_ID36
Reading employee started
Read employee record: EMP_ID37
Reading employee started
Read employee record: EMP_ID38
Reading employee started
Read employee record: EMP_ID39
Reading employee started
Read employee record: EMP_ID40
Reading employee started
Read employee record: EMP_ID41
Reading employee started
Read employee record: EMP_ID42
Reading employee started
Read employee record: EMP_ID43
Reading employee started
Read employee record: EMP_ID44
Reading employee started
Read employee record: EMP_ID45
Reading employee started
Read employee record: EMP_ID46
Reading employee started
Read employee record: EMP_ID47
Reading employee started
Read employee record: EMP_ID48
Reading employee started
Read employee record: EMP_ID49
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Writing is started
Writing is completed
Reading employee started
Read employee record: EMP_ID50
Reading employee started
Read employee record: EMP_ID51
Reading employee started
Read employee record: EMP_ID52
Reading employee started
Read employee record: EMP_ID53
Reading employee started
Read employee record: EMP_ID54
Reading employee started
Read employee record: EMP_ID55
Reading employee started
Read employee record: EMP_ID56
Reading employee started
Read employee record: EMP_ID57
Reading employee started
Read employee record: EMP_ID58
Reading employee started
Read employee record: EMP_ID59
Reading employee started
Read employee record: EMP_ID60
Reading employee started
Read employee record: EMP_ID61
Reading employee started
Read employee record: EMP_ID62
Reading employee started
Read employee record: EMP_ID63
Reading employee started
Read employee record: EMP_ID64
Reading employee started
Read employee record: EMP_ID65
Reading employee started
Read employee record: EMP_ID66
Reading employee started
Read employee record: EMP_ID67
Reading employee started
Read employee record: EMP_ID68
Reading employee started
Read employee record: EMP_ID69
Reading employee started
Read employee record: EMP_ID70
Reading employee started
Read employee record: EMP_ID71
Reading employee started
Read employee record: EMP_ID72
Reading employee started
Read employee record: EMP_ID73
Reading employee started
Read employee record: EMP_ID74
Reading employee started
Read employee record: EMP_ID75
Reading employee started
Read employee record: EMP_ID76
Reading employee started
Read employee record: EMP_ID77
Reading employee started
Read employee record: EMP_ID78
Reading employee started
Read employee record: EMP_ID79
Reading employee started
Read employee record: EMP_ID80
Reading employee started
Read employee record: EMP_ID81
Reading employee started
Read employee record: EMP_ID82
Reading employee started
Read employee record: EMP_ID83
Reading employee started
Read employee record: EMP_ID84
Reading employee started
Read employee record: EMP_ID85
Reading employee started
Read employee record: EMP_ID86
Reading employee started
Read employee record: EMP_ID87
Reading employee started
Read employee record: EMP_ID88
Reading employee started
Read employee record: EMP_ID89
Reading employee started
Read employee record: EMP_ID90
Reading employee started
Read employee record: EMP_ID91
Reading employee started
Read employee record: EMP_ID92
Reading employee started
Read employee record: EMP_ID93
Reading employee started
Read employee record: EMP_ID94
Reading employee started
Read employee record: EMP_ID95
Reading employee started
Read employee record: EMP_ID96
Reading employee started
Read employee record: EMP_ID97
Reading employee started
Read employee record: EMP_ID98
Reading employee started
Read employee record: EMP_ID99
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Item processing started
Item processing completed
Writing is started
Writing is completed
Reading employee started
Oct 13, 2018 12:53:41 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run
INFO: Job: [FlowJob: [name=importProductsJob]] completed with the following parameters: [{date=1539415420709}] and the following status: [COMPLETED]

Leave a Reply