Spring Batch3

Spring Batch TaskScheduler Example

Why do we need scheduling?

Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 10 seconds just to hit the Enter key? No one.

In this example we use a simple configuration and an example implementation of ItemReader and ItemWriter, as you can see below. The Job is defined to run every 10 seconds. While everything works well in the first iteration, reading and writing seems to be skipped in the subsequent iterations.

<batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="xmlItemReader" writer="mongodbItemWriter" commit-interval="2" processor="employeeFilter"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
<bean id="runScheduler" class="com.doj.batch.scheduler.RunScheduler" />
 
  <!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>

In this tutorial, we will show you how to use Spring TaskScheduler to schedule a batch job to run every 5 seconds.

Tools and libraries used

  • Spring Tool Suite (STS)
  • JDK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE
  • MongoDB Java Driver 2.7.3
  • MongoDB 2.10.1

1. Project Directory Structure

2. Spring TaskScheduler

Spring 3.0 introduces a TaskScheduler for scheduling tasks. It is part of the Spring-Core, no need to declare an extra dependency. A scheduler triggers launch Spring Batch jobs, by accessing the Spring Batch runtime.

<!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>
  <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" fixed-delay="10000" />
   </task:scheduled-tasks>

The TaskScheduler will schedule to run below bean.

package com.doj.batch.scheduler;

import java.util.Date;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Dinesh Rajput
 *
 */
@Component
public class RunScheduler {
 @Autowired
 private JobLauncher jobLauncher;
  
 @Autowired
 private Job job;
 
 public void run() {
     try {
   String dateParam = new Date().toString();
   JobParameters param = new JobParametersBuilder().addString("date", dateParam).toJobParameters();
   System.out.println(dateParam);
   JobExecution execution = jobLauncher.run(job, param);
   System.out.println("Exit Status : " + execution.getStatus());
     } catch (Exception e) {
      //e.printStackTrace();
     }
   }
}

Input XML File
employees.xml

s<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>delhi</address>
  <age>37</age>
  <empid>1111</empid>
  <name>ATUL KUMAR</name>
  <salary>300000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>27</age>
  <empid>2222</empid>
  <name>Dinesh Rajput</name>
  <salary>60000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>31</age>
  <empid>3333</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
 <employee>
  <address>Kanpur</address>
  <age>27</age>
  <empid>4444</empid>
  <name>Adesh Verma</name>
  <salary>80000.0</salary>
 </employee>
 <employee>
  <address>Noida</address>
  <age>37</age>
  <empid>5555</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>

Employee.java

package com.doj.batch.bean;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employee")
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
 public String toString(){
  return "Name- "+name+" Age- "+age+" salary- "+salary+" address "+address;
 }
 
}

4. Job configuration
simple-job.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:task="http://www.springframework.org/schema/task"
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd">
 <context:component-scan base-package="com.doj.batch" />
 <import resource="applicationContext.xml"/>
 <import resource="mongodbConfig.xml"/>
 
 <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>
 <bean id="empUnMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean>
 <!-- write it to MongoDB, 'employee' collection (table) -->
    <bean id="mongodbItemWriter" class="org.springframework.batch.item.data.MongoItemWriter">
  <property name="template" ref="mongoTemplate" />
  <property name="collection" value="employee" />
    </bean>
    
    <bean id="employeeFilter" class="com.doj.batch.process.EmployeeFilter"></bean>
    
    <batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="xmlItemReader" writer="mongodbItemWriter" commit-interval="2" processor="employeeFilter"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
    
    <bean id="runScheduler" class="com.doj.batch.scheduler.RunScheduler" />
 
  <!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>
</beans>

Run It-

Loads the Spring application context, the scheduler will be run automatically.
TestBatch.java

package com.doj.batch.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Dinesh Rajput
 *
 */
public class TestBatch {

 /**
  * @param args
  */
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext("simple-job.xml");
 }

}

Output, it insert the xml content every 10 seconds in mongodb.

…………
…………..
Mar 9, 2014 5:43:18 PM org.springframework.oxm.jaxb.Jaxb2Marshaller createJaxbContextFromClasses
INFO: Creating JAXBContext with classes to be bound [class com.doj.batch.bean.Employee]
Sun Mar 09 17:43:20 IST 2014
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [FlowJob: [name=simpleDojJob]] launched with the following parameters: [{date=Sun Mar 09 17:43:20 IST 2014}]
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.job.AbstractJob handleStep
INFO: Executing step: [TaskletStep: [name=step1]]
Name- ATUL KUMAR Age- 37 salary- 300000.0 address delhi
Mar 9, 2014 5:43:20 PM org.springframework.oxm.jaxb.Jaxb2Marshaller processSource
Name- ASHUTOSH RAJPUT Age- 31 salary- 400000.0 address delhi
Mar 9, 2014 5:43:20 PM org.springframework.oxm.jaxb.Jaxb2Marshaller processSource
Name- Dinesh Rajput Age- 37 salary- 300000.0 address Noida
Exit Status : COMPLETED
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [FlowJob: [name=simpleDojJob]] completed with the following parameters: [{date=Sun Mar 09 17:43:20 IST 2014}] and the following status: [COMPLETED]
Sun Mar 09 17:43:30 IST 2014
………………….
………………………

Download Source Code with Jars
SpringBatchTaskSchedulerExample.zip

 

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…

3 years ago