Simple Spring Batch Job using Job, Step and Tasklet

Job – Big Picture, Step – building block, Tasklet – Worker

Component Role Typical Use Case
Job Orchestrates steps Full batch process
Step Executes a unit of work Reading, processing, writing
Tasklet Performs a single task Logging, cleanup, file ops

OrderSchedulerApplication.java

package com.mugil.org;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

BatchConfig.java

package com.mugil.org.config;

import org.springframework.batch.core.*;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class BatchConfig {
    @Bean
    public Job job(JobRepository jobRepository, Step step) {
        return new JobBuilder("job", jobRepository)
                .start(step)
                .build();
    }

    @Bean
    public Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        StepBuilder stepBuilderOne = new StepBuilder("step1", jobRepository);
        return stepBuilderOne.tasklet(helloWorldTasklet(), transactionManager)
                .build();
    }

    @Bean
    public Tasklet helloWorldTasklet() {
        return (StepContribution contribution, ChunkContext chunkContext) -> {
            System.out.println("Hello, World!");
            return RepeatStatus.FINISHED;
        };
    }
}

Output

2025-08-30T15:33:46.902+05:30  INFO 3620 --- [OrderScheduler] [           main] o.s.b.c.l.s.TaskExecutorJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{}]
2025-08-30T15:33:46.909+05:30  INFO 3620 --- [OrderScheduler] [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
Hello, World!
2025-08-30T15:33:46.914+05:30  INFO 3620 --- [OrderScheduler] [           main] o.s.batch.core.step.AbstractStep         : Step: [step1] executed in 3ms
2025-08-30T15:33:46.917+05:30  INFO 3620 --- [OrderScheduler] [           main] o.s.b.c.l.s.TaskExecutorJobLauncher      : Job: [SimpleJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 9ms

Having separate Tasklet
HelloWorldTasklet.java

public class HelloWorldTasklet implements Tasklet {
    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        System.out.println("Hello, World!");
        return RepeatStatus.FINISHED;
    }
}

FAQ

  1. You cannot have multiple Tasklets however you can have multiple Steps

For the above job the following tables would be impacted.

  1. batch_job_instance(unique job entity which needs to run)
  2. batch_job_execution(Instance may have one execution if execution is success or more than one execution if failed)
  3. batch_step_execution(Job would have multiple steps)
  4. batch_job_execution_context(Context which is shared by among different steps in job)
SELECT BJI.job_name, BSE.step_name, BJE.start_time, BJE.end_time, BJE.status as job_staus, 
       BSE.status as step_staus,  BJE.exit_code, BJE.exit_message
  FROM public.batch_job_instance   BJI INNER JOIN 
       public.batch_job_execution  BJE ON BJE.job_instance_id = BJI.job_instance_id INNER JOIN 
       public.batch_step_execution BSE ON BJE.job_execution_id = BSE.job_execution_id	   
 WHERE BJE.job_execution_id=1;

Job Execution Context and Step Execution Context
Job Execution Context – Available throughout the entire job execution across various steps. Stores data that needs to be shared across multiple steps or retrieved after a job restart. it survives restarts and failures.

I.E.
If you download a file in Step 1 and need its path in Step 3, store the path in the Job Execution Context.

Step Execution Context – Limited to the specific step execution.Stores data relevant only to that step, such as reader/writer state or counters.
I.E.
A reader might store the last read line number here so it can resume from that point if the step fails. We can pass values between steps and jobs using ExecutionContextPromotionListener.

Comments are closed.