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.