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
- You cannot have multiple Tasklets however you can have multiple Steps
For the above job the following tables would be impacted.
- batch_job_instance(unique job entity which needs to run)
- batch_job_execution(Instance may have one execution if execution is success or more than one execution if failed)
- batch_step_execution(Job would have multiple steps)
- 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.