Job Scheduling with Spring Batch

 Spring Batch

Spring Batch is a processing framework designed for robust and parallel execution of multiple job. It follows the standard batch architecture in which a job repository takes care of scheduling and interacting with the job.

 Spring Batch Job

Spring batch job reads input data, processes the input data, and writes the processed data to the configured output.

  Spring Batch Job processing

 

Spring Batch job consists of the following components as shown in above image:

  • The JobLauncher, which is a simple interface is used to manage the jobs.
  • The Job represents the Batch job. Each job is comprised of one or more step.
  • The Step represents a logical task (i.e. read data from DB). Each step belongs to a single job.
  • The JobRepository is responsible for storing each Java object into its correct meta-data table for spring batch.
  • The Item-Reader reads the input data from a file or database and gives us the items.
  • The Item-Processor : it is used if any processing required for the data. It process the data and send to the ItemWriter.
  • The Item-Writer writes out (store) data of an item to the database or in output files.

The following figure define a simple batch job

 

Above image describe a job only, not a batch job. Let us try to visualize a batch job with following image:

 

Now, the above diagram is a better description of a batch job which includes multiple jobs. When all jobs are done then the batch can be declared as done.

Example Of Spring Batch

What we’ll build

We will build a job that will read a string value from an array, convert it into upper case and print on console.

This job will perform its task in one step and this step will have a reader that will read a string value from an array, a processor that will transform a string value in uppercase and a writer that will print transformed string on console.

What we’ll need

  • Java 1.8
  • Maven 3.3.9
  • Spring Boot: 1.4.0.RELEASE

1. Required dependencies

Add these dependencies

<project xmlns="http://maven.apache.org/POM/4.0.0"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   
http://maven.apache.org/xsd/maven-4.0.0.xsd">

<project>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

</project>

 

2. Create Steps: Reader, Processor and Writer

  •  we will create a Reader.java class which implements a ItemReader interface. We use it to get data by read() method. This will read string from array one by one and forward to processor. If all data are consumed, then a null value will be returned by this method.
public class ReaderImpl implements ItemReader<String>{
	private String[] msgArray= {"Hi","Welcome","To","Spring","batch","!!"};
	private int count=0;
	@Override
	public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {	
		if(count < msgArray.length){
			return msgArray[count++];
		}else{
			count=0;
		}
		return null;
	}
}

 

  •  Now we will make a Processor.java class which imlements an interface ItemProcessor. it  is used to process the input data. We can provide output and input data type for each ItemProcessor. This will change the string in upper case.
public class ProcessorImpl implements ItemProcessor<String, String>{
	@Override
	public String process(String message) throws Exception {
		return message.toUpperCase();
	}
}
  •  Now create a Writer.java class which implements an interface ItemWriter. We use it to generate output of batch processing. The write() method get a list of items from batch processor or batch reader to process it. This will print changed string.
public class WriterImpl implements ItemWriter<String> {
	@Override
	public void write(List<? extends String> msgArray) throws Exception {
		for(String msg : msgArray){
			System.out.println("In writer: " + msg);
		}
	}
}

3. Make the application executable

Although we can make WAR file of batch processing ,but here we are making  a standalone application, in this approach we package everything in a single, executable JAR file and run as a standalone application.

In SprinpBatchApplication class, @EnableBatchProcessing is used to include Spring Batch features and provide a configuration for setting up batch jobs in a @Configuration class.

@SpringBootApplication
@EnableBatchProcessing
public class SprinpBatchApplication {
	public static void main(String[] args) {
		SpringApplication.run(SprinpBatchApplication.class, args);
	}
}

4.Spring Batch Configuration

Create a configuration file and enable Spring batch via annotations: @Configuration

@Configuration
public class BatchConfig {
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;

@Autowired
private SimpleJobLauncher jobLauncher;
    
@Scheduled(cron = "0 0 8 1/1 * ?")	
public void sendSmsForExpiringBookmark() throws Exception 
{
System.out.println(" Job Started at :"+ new Date());
JobParameters param = new JobParametersBuilder().addString("JobID",
String.valueOf(System.currentTimeMillis())).toJobParameters();
JobExecution execution = jobLauncher.run(job(), param);
System.out.println("Job finished with status :" + execution.getStatus());
}   
    public Job job() {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }

  
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, String> chunk(1)
                .reader(new Reader())
                .processor(new Processor())
                .writer(new Writer())
                .build();
    }

5. Spring Batch Job Configuration

@Configuration
@EnableScheduling
public class BatchScheduler {

	@Bean
	public ResourcelessTransactionManager transactionManager() {
		return new ResourcelessTransactionManager();
	}

	@Bean
	public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
	ResourcelessTransactionManager txManager) throws Exception {
	MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(
				txManager);
		factory.afterPropertiesSet();
		return factory;
	}
	
       @Bean
	public JobRepository jobRepository(MapJobRepositoryFactoryBean factory)
			throws Exception {
		return (JobRepository) factory.getObject();
	}

	@Bean
	public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
		SimpleJobLauncher launcher = new SimpleJobLauncher();
		launcher.setJobRepository(jobRepository);
		return launcher;
	}

}

6.Build an executable JAR file of Batch Job

We will build a single executable JAR  that contains all the required dependencies, classes, and resources.

 We can build the JAR file with mvn clean package, and run the JAR file:

java -jar inno-batch-processing-0.1.0.jar

 

Note: The above  procedure will create a runnable JAR file, but you can also build a classic                    WAR file from here.

Leave a Reply