Spring Batch3

Hello World With Spring Batch 2.0.x

In this tutorial we will write simple Hello World application using Spring Batch 2.0. This is an introductory tutorial to Spring Batch.

Spring Batch Introduction-

Many applications within the enterprise domain require bulk processing to perform business critical operations. These business operations include automated, complex processing of large volumes of information that is most efficiently processed without user intervention.

Some Batch Terminologies-

Before we look into the details of Spring Batch, lets look at some important terms that will be used in this article and anywhere in context of Spring Batch. You have to read the following post.
1. Configuring and running jobs
2. Configuring Steps
3. ItemReader & ItemWriter
4. Some Domain Params
5. Read Spring Batch Terms

Spring Batch is a lightweight batch framework which enables the development of a batch applications for the daily operations of enterprise systems.

In this example, we will be explaining Spring Batch classes and interfaces using a simple Hello World example. We will create a job which consists of two steps. One prints “Hello World!” and second prints “Created By Dinesh On Java”. Aim is to keep the example simple and still understand the power of Spring Batch Framework.

Create Application Context XML-

In order to run Spring Batch, we need to configuration Spring Batch Infrastructure. This includes creation of JobRepository, JobLauncher and TransactionManager.

For each job, we will use a separate xml context definition file. However there is a number of common objects that we will need recurrently. I will group them in an applicationContext.xml which will be imported from within job definitions. Let’s go through these common objects:
JobLauncher-

JobLaunchers are responsible for starting a Job with a given job parameters. The provided implementation, SimpleJobLauncher, relies on a TaskExecutor to launch the jobs. If no specific TaskExecutor is set then a SyncTaskExecutor is used.
JobRepository-

We will use the SimpleJobRepository implementation which requires a set of execution Daos to store its information.
JobInstanceDao, JobExecutionDao, StepExecutionDao-

These data access objects are used by SimpleJobRepository to store execution related information. Two sets of implementations are provided by Spring Batch: Map based (in-memory) and Jdbc based. In a real application the Jdbc variants are more suitable but we will use the simpler in-memory alternative in this example.

Here’s our applicationContext.xml:

<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
 <import resource="MEMORY-JOBREPOSITORY.xml"/>

</beans>

Here’s our MEMORY-JOBREPOSITORY.xml:

<beans xmlns:batch="http://www.springframework.org/schema/batch" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 
 
<bean class="org.springframework.batch.core.repository.support.SimpleJobRepository" id="jobRepository">  
    <constructor-arg><bean class="org.springframework.batch.core.repository.dao.MapJobInstanceDao"/> 
    </constructor-arg><constructor-arg>bean class="org.springframework.batch.core.repository.dao.MapJobExecutionDao" /> 
    </constructor-arg><constructor-arg><bean class="org.springframework.batch.core.repository.dao.MapStepExecutionDao"/> 
     </constructor-arg><constructor-arg><bean class="org.springframework.batch.core.repository.dao.MapExecutionContextDao"/> 
    </constructor-arg></bean>      <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>     <bean class="org.springframework.batch.core.launch.support.SimpleJobLauncher" id="jobLauncher">     <property name="jobRepository" ref="jobRepository"/>    </bean>    </beans>

 

Create HelloWorldTasklet.java class-

A tasklet is a class containing custom logic to be run as a part of a job. HelloWorldTasklet is our custom tasklet which implements Tasklet interface and overrides the execute() method. It is a simple tasklet that simply prints a message.

Note that the execute method returns RepeatStatus to indicate execution status of tasklet.
RepeatStatus.FINISHED indicates that processing is finished (either successful or unsuccessful)
RepeatStatus.CONTINUABLE indicates that processing can continue.

package com.dineshonjava.batch.hello;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

/**
 * 
 * @author Dinesh Rajput
 *
 */
public class HelloWorldTasklet implements Tasklet {
 
 private String message;
  
    public void setMessage(String message) {
        this.message = message;
    }
    
 @Override
 public RepeatStatus execute(StepContribution contribution, ChunkContext context)
   throws Exception {
  System.out.println(message);
  return RepeatStatus.FINISHED;
 }

}

Create Job Configuration XML-

In this section we will see configuration to fit the custom tasklet into the Spring Batch framework.

<beans xmlns:batch="http://www.springframework.org/schema/batch" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
 <import resource="applicationContext.xml"/>
 
    <bean abstract="true" class="org.springframework.batch.core.step.tasklet.TaskletStep" id="taskletStep">
        <property name="jobRepository" ref="jobRepository"/>
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
 
    <bean class="com.dineshonjava.batch.hello.HelloWorldTasklet" id="helloTasklet">
       <property name="message" value="Hello World!"/>
    </bean>
 
    <bean class="com.dineshonjava.batch.hello.HelloWorldTasklet" id="createdByTasklet">
        <property name="message" value="Created By Dinesh On Java"/>
    </bean>
    
 
    <bean class="org.springframework.batch.core.job.SimpleJob" id="mySimpleJob">
        <property name="name" value="mySimpleJob" />
        <property name="steps">
            <list>
                <bean parent="taskletStep">
                   <property name="tasklet" ref="helloTasklet"/>
                </bean>
 
               <bean parent="taskletStep">
                    <property name="tasklet" ref="createdByTasklet"/>
                </bean>
            </list>
        </property>
        <property name="jobRepository" ref="jobRepository">
    </bean>
</beans>

First we created an abstract bean (“taskletStep“) using class TaskletStep. We injected job repository and transaction manager into this tasklet. Later we created two instance of our HelloWorldTasklet class, one of which takes “Hello World!” as message and another takes “Created By Dinesh On Java” as message.
Finally we defined our batch job (“mySimpleJob“) consisting of two steps using class SimpleJob. Property “steps” takes list of tasklet steps which will be executed sequentially one after another.
As the two tasklet instances which we created earlier represent a step in our batch application, they use taskletStep abstract bean as parent.

Running the Job-

Now we need something to kick-start the execution of our jobs. Spring Batch provides a convenient class to achieve that from the command line: CommandLineJobRunner. In its simplest form this class takes 2 arguments:
1. the xml application context containing the job to launch(simpleJob.xml) and
2. the bean id of that job(mySimpleJob).
It naturally requires a JobLauncher to be configured in the application context.

First right click to project “springBatch2HelloWorld” and click on Run As and go to Run Configurations… as follows…

After clicking on the Run Configurations… we get the following window and put the information as on Project field with value “springBatch2HelloWorld” and Main Class field with value “org.springframework.batch.core.launch.support.CommandLineJobRunner

Now switch to Arguments tabs on the above window we get the following window and put the value on the Program arguments as “config/simpleJob.xml mySimpleJob“. and click on the Run button.

After clicking Run button if every thing is Ok then we will get the following output on the console.

OUTPUT:
Jan 15, 2013 12:00:27 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1100d7a: startup date [Tue Jan 15 00:00:27 IST 2013]; root of context hierarchy
Jan 15, 2013 12:00:27 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [config/simpleJob.xml]
Jan 15, 2013 12:00:27 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [config/applicationContext.xml]
Jan 15, 2013 12:00:27 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [config/MEMORY-JOBREPOSITORY.xml]
Jan 15, 2013 12:00:27 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d85f79: defining beans [jobRepository,transactionManager,jobLauncher,taskletStep,helloTasklet,createdByTasklet,mySimpleJob]; root of factory hierarchy
Jan 15, 2013 12:00:27 AM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet
INFO: No TaskExecutor has been set, defaulting to synchronous executor.
Jan 15, 2013 12:00:27 AM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [SimpleJob: [name=mySimpleJob]] launched with the following parameters: [{}]
Jan 15, 2013 12:00:27 AM org.springframework.batch.core.job.AbstractJob handleStep
INFO: Executing step: [TaskletStep: [name=taskletStep$child#1ea5671]]
Hello World!
Jan 15, 2013 12:00:27 AM org.springframework.batch.core.job.AbstractJob handleStep
INFO: Executing step: [TaskletStep: [name=taskletStep$child#1d15445]]
Created By Dinesh On Java
Jan 15, 2013 12:00:27 AM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [SimpleJob: [name=mySimpleJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]
Jan 15, 2013 12:00:27 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1100d7a: startup date [Tue Jan 15 00:00:27 IST 2013]; root of context hierarchy
Jan 15, 2013 12:00:27 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d85f79: defining beans [jobRepository,transactionManager,jobLauncher,taskletStep,helloTasklet,createdByTasklet,mySimpleJob]; root of factory hierarchy

Download SourceCode+Libs

 

 

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

2 years ago