How to use Intercepting Job Execution in Spring Batch

For Intercepting Job Execution feature, Spring Batch provides an interface called JobExecutionListener to notify events in a Job lifecycle. So in the tutorial, JavaSampleApproach will guide how to configure Intercepting Job Execution with JobExecutionListener.

Related Posts:
1. How to start with Spring Batch using Spring Boot – Java Config
2. Spring Batch XML Config by Spring Boot
3. How to use Spring Batch Inheritance function

I. Technologies

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE
– Spring Boot: 1.5.1.RELEASE
– MySQL Database 1.4

II. Intercepting Job Execution

For Intercepting Job Execution, Spring Batch provides an interface JobExecutionListener:

public interface JobExecutionListener {

    void beforeJob(JobExecution jobExecution);
    void afterJob(JobExecution jobExecution);

}

Function void beforeJob(JobExecution jobExecution): is invoked before a job executes.
Function void afterJob(JobExecution jobExecution): is invoked after completion of a job.

For register a job execution listener with Java config, use:
org.springframework.batch.core.job.builder.JobBuilderHelper.listener(JobExecutionListener listener)

@Bean
public Job job() {
    return jobBuilderFactory.get("job")
            .incrementer(new RunIdIncrementer())
            .flow(step1())
            .end()
            // configure Intercepting-Job here
            .listener(interceptingJob)
            .build();
}

For XML register a job execution listener, use: listeners


    
        
            
        
    
    
    
    	
	

III. Practice

Step to do:
– Create Spring Boot project
– Create a Job Step
– Create a JobExecutionListener
– Configure Batch Job
– Create a Launch Controller
– Run & Check result

1. Create Spring Boot project

Create a Spring Boot project with needed dependencies:
spring-boot-starter-batch
spring-boot-starter-web
mysql-connector-java


	org.springframework.boot
	spring-boot-starter-batch


	org.springframework.boot
	spring-boot-starter-web



	mysql
	mysql-connector-java
	runtime

2. Create Job Step

Create a simple Job step with Reader, Writer and Processor:
Reader.java:

package com.javasampleapproach.intercepting.step;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
 
 
public class Reader implements ItemReader{
 
    private String[] messages = {"Hello World!", "Welcome to Spring Batch!"};
     
    private int count=0;
     
    Logger logger = LoggerFactory.getLogger(this.getClass());
     
    @Override
    public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
         
        if(count < messages.length){
            return messages[count++];
        }else{
            count=0;
        }
        return null;
    }
     
}

- Writer.java:

package com.javasampleapproach.intercepting.step;
 
import java.util.List;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemWriter;
 
public class Writer implements ItemWriter {
 
    Logger logger = LoggerFactory.getLogger(this.getClass());
     
    @Override
    public void write(List messages) throws Exception {
        for(String msg : messages){
            System.out.println("#Writer Step: " + msg);
        }
    }
     
}

- Processor.java:

package com.javasampleapproach.intercepting.step;
 
import org.springframework.batch.item.ItemProcessor;
 
public class Processor implements ItemProcessor{
 
    @Override
    public String process(String content) throws Exception {
        return content.toUpperCase();
    }
 
}
3. Create a JobExecutionListener

Create a Intercepting Job Execution by implementing interface: JobExecutionListener

package com.javasampleapproach.intercepting.listener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.stereotype.Component;

@Component
public class InterceptingJobExecution implements JobExecutionListener{
	
	private Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void beforeJob(JobExecution jobExecution) {
		//
		// Can Log || do some business code
		//
		log.info("Intercepting Job Excution - Before Job!");
	}

	@Override
	public void afterJob(JobExecution jobExecution) {
		//
		// Can Log || do some Business code
		//
		log.info("Intercepting Job Excution - After Job!");
	}

}
4. Config Batch Job

- Java Config, use:org.springframework.batch.core.job.builder.JobBuilderHelper.listener(JobExecutionListener listener)

package com.javasampleapproach.intercepting.config;
 
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.javasampleapproach.intercepting.listener.InterceptingJobExecution;
import com.javasampleapproach.intercepting.step.Processor;
import com.javasampleapproach.intercepting.step.Reader;
import com.javasampleapproach.intercepting.step.Writer;

 
@Configuration
public class BatchConfig {
 
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
 
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
 
    @Autowired
    InterceptingJobExecution interceptingJob;
    
     
    @Bean
    public Job job() {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                // configure Intercepting-Job here
                .listener(interceptingJob)
                .build();
    }
 
    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                . chunk(1)
                .reader(new Reader())
                .processor(new Processor())
                .writer(new Writer())
                .build();
    }

}

- XML config, use: listeners



	
		
			
				
			
		

		
			
		
	

	
	
	

	
	


- Open application.properties file to configure database for batch job:

spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=12345
spring.batch.job.enabled=false

- Enable Batch Job config:

package com.javasampleapproach.intercepting;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableBatchProcessing
@SpringBootApplication
public class SpringBatchJobExecutionApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBatchJobExecutionApplication.class, args);
	}
}

With XML config, need import batchjob.xml file: @ImportResource("classpath:batchjob.xml")

5. Create a Launch Controller

Create a simple controller for launching job:

package com.javasampleapproach.intercepting.controller;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class JobLauncherController {
 
    @Autowired
    JobLauncher jobLauncher;
 
    @Autowired
    Job job;
    
    @RequestMapping("/launchjob")
    public String handle() throws Exception {
 
        Logger logger = LoggerFactory.getLogger(this.getClass());
        try {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
                    .toJobParameters();
            jobLauncher.run(job, jobParameters);
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
 
        return "Done";
    }
}
6. Run & Check result

- Build & Run the project with Spring Boot mode.
- Launch the Job by a request: http://localhost:8080/launchjob

o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=job]] launched with the following parameters: [{time=1487930196844}]
c.j.i.listener.InterceptingJobExecution  : Intercepting Job Excution - Before Job!
o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
#Writer Step: HELLO WORLD!
#Writer Step: WELCOME TO SPRING BATCH!
c.j.i.listener.InterceptingJobExecution  : Intercepting Job Excution - After Job!
o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=job]] completed with the following parameters: [{time=1487930196844}] and the following status: [COMPLETED]

IV. Sourcecode

1. SpringBatchInterceptingJobExecution
2. SpringBatchInterceptingJobExecutionXMLConfig



By grokonez | February 24, 2017.

Last updated on June 4, 2017.



Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*