How to use Spring Batch Inheritance function

In the tutorial, JavaSampleApproach will introduce about inheritance feature of Spring Batch: Inheriting from a Parent Job & Inheriting from a Parent Step.

Related post:
How to use Intercepting Job Execution in Spring Batch

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. Inheritance feature

Spring Batch provides Inheritance feature for Batch Job scope & Batch Job Step.
Inheriting from a Parent Job: It is helpful idea for jobs can share the similar configuration from a parent job.
Sample:



    
        
    



    ...
    
        
    

Merging Lists: Some of Step configurable elements are lists; like . If parent & child Steps has a , then the child’s list will override the parent’s. For a child to have both listeners (an additional element from parent), every list element must use “merge” attribute.
In above example, the child Job with id=”job” has both listener: baseListeners & interceptingJobExecution

Inheriting from a Parent Step: When a group of Steps have similar configurations, parent Step is a good idea from which the concrete Steps can inherit properties.
Sample:



    
        
    

	

    
    ...

“abstract” attribute is used to defined an Abstract Step which will not be instantiated. Abstract Step is just used only for extending.

III. Practices

Create a Spring Boot project with 2 batch jobs:
– 1 parent Job (abstract job)
– 1 abstract Step
– 1 child job has a Step which inherits from the abstract Step.

Spring batch inheritance

Step to do:
– Create Spring Boot project
– Create a Job Step
– Create JobExecutionListeners
– 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 a 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 JobExecutionListeners

- Create BaseListener.java for a Parent Job:

package com.javasampleapproach.inheritance.listener;

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

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

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

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

}

- For a child Job, create InterceptingJobExecution.java listener:

package com.javasampleapproach.inheritance.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. Configure Batch Job


	
	
	    
	        
	    
	
	
	
	
	           
	               
	           
	   
		
	
	    
	    
	    
	        
	    
	
 
    
    
    
 
    
    
    
    
 

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

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

- Enable Batch Job in main class:
@EnableBatchProcessing
@ImportResource("classpath:batchjob.xml")

5. Create a Launch Controller
package com.javasampleapproach.inheritance.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 App mode.
- Make a request for launch a Job: localhost:8080/launchjob
Result:

o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=job]] launched with the following parameters: [{time=1488043301815}]
c.j.inheritance.listener.BaseListener    : # Base Job Listener - Intercepting Job Excution - Before Job!
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!
c.j.inheritance.listener.BaseListener    : # Base Job Listener - Intercepting Job Excution - After Job!
o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=job]] completed with the following parameters: [{time=1488043301815}] and the following status: [COMPLETED]
IV. Sourcecode

- SpringBatchInheritanceFeature



By grokonez | February 25, 2017.

Last updated on June 4, 2017.



Related Posts


Got Something To Say:

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

*