Simplified Guide to Using Tasklet in Spring Batch with Spring Boot

How to Use Tasklet in Spring Batch with Spring Boot

If you are building an enterprise application using Spring Batch, you will quickly realize that not every batch job involves reading thousands of records from a database, processing them, and writing them to a file. Sometimes, you just need to execute a single, highly specific task—like deleting old temporary files, invoking a stored procedure, calling an external REST API, or sending a summary email.

For these single-pass operations, Spring Batch provides the Tasklet interface. In this comprehensive guide, we will explore the architecture of a Tasklet, when to use it over chunk processing, and how to implement it correctly using modern Spring Boot 3+ and Spring Batch 5+ standards.

📺 Visual Learner? Explore the Complete Spring Batch Playlist!
Master the entire Spring Batch framework from basic Tasklets to complex Chunk processing, scaling, and fault tolerance by watching my comprehensive video series.

▶ Watch the Spring Batch Masterclass Playlist

1. Tasklet vs. Chunk Processing: Architectural Differences

Before writing code, it is crucial to understand which Spring Batch pattern fits your use case. Choosing the wrong pattern leads to over-engineered, difficult-to-maintain code.

FeatureTasklet StepChunk-Oriented Step
Execution ModelExecutes the entire task in a single method call.Loops continuously (Read → Process → Write) until data is exhausted.
Primary Use CaseFile cleanup, zip/unzip operations, API triggers, sending emails.Migrating millions of database rows, generating large CSV reports.
ComplexityLow. Requires implementing a single execute() method.High. Requires configuring an ItemReader, ItemProcessor, and ItemWriter.

2. Maven Dependencies (Spring Boot 3+)

To utilize Tasklets, you only need the core Spring Batch starter. (Assuming you already have a database driver configured for the Spring Batch metadata tables).

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

3. Deep Dive: The Tasklet Interface

Under the hood, a Tasklet is simply a functional interface with a single method: execute. Let's look at the method signature:

public interface Tasklet {
    RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}
  • StepContribution: Allows you to pass data or status updates back to the overarching Step execution (e.g., incrementing read/write counts).
  • ChunkContext: Provides access to the execution context, allowing you to fetch JobParameters or pass state to subsequent steps.
  • RepeatStatus: You must return RepeatStatus.FINISHED to tell Spring Batch the task is complete. If you return RepeatStatus.CONTINUABLE, Spring Batch will loop and call your Tasklet again.

4. Real-World Example: A File Cleanup Tasklet

While you can write a Tasklet inline using a Lambda, it is best practice in enterprise apps to create a dedicated class for complex logic. This makes your code highly testable and reusable. Here is a Tasklet designed to clean up temporary directories before a job starts:

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import java.io.File;

@Slf4j
@Component
public class FileCleanupTasklet implements Tasklet {

    private final String directoryPath = "/tmp/batch-processing/";

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        log.info("Starting FileCleanupTasklet for directory: {}", directoryPath);
        
        File directory = new File(directoryPath);
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    boolean deleted = file.delete();
                    log.info("File {} deleted: {}", file.getName(), deleted);
                }
            }
        }
        
        log.info("File cleanup completed successfully.");
        return RepeatStatus.FINISHED;
    }
}

5. Job Configuration (Spring Batch 5 Standards)

Now we need to wire our Tasklet into a Spring Batch Job.

Spring Batch 5 Alert: In older versions of Spring Batch, you could use StepBuilderFactory. In Spring Batch 5+, factories are deprecated. You must use StepBuilder directly and explicitly pass a PlatformTransactionManager to your Tasklet step.
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
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 BatchTaskletConfig {

    // 1. Defining a Step using our dedicated Class Tasklet
    @Bean
    public Step fileCleanupStep(JobRepository jobRepository, 
                                PlatformTransactionManager txManager, 
                                FileCleanupTasklet fileCleanupTasklet) {
                                
        return new StepBuilder("fileCleanupStep", jobRepository)
                .tasklet(fileCleanupTasklet, txManager)
                .build();
    }

    // 2. Defining a Step using a Lambda (Great for simple logic)
    @Bean
    public Step simpleLogStep(JobRepository jobRepository, PlatformTransactionManager txManager) {
        return new StepBuilder("simpleLogStep", jobRepository)
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("Executing simple lambda tasklet logic...");
                    return RepeatStatus.FINISHED;
                }, txManager).build();
    }

    // 3. Orchestrating the Job
    @Bean
    public Job taskletJob(JobRepository jobRepository, Step fileCleanupStep, Step simpleLogStep) {
        return new JobBuilder("sampleTaskletJob", jobRepository)
                .start(fileCleanupStep) // Runs first
                .next(simpleLogStep)    // Runs second
                .build();
    }
}

Conclusion

The Tasklet is a powerful, lightweight mechanism in Spring Batch. Whether you are using a concise Lambda expression for a simple log statement, or a dedicated Class to handle complex file I/O operations, Tasklets are the standard way to handle non-chunking workloads. Just remember, if you migrate to Spring Batch 5, always inject and provide the PlatformTransactionManager to your Step builder!

⚙️ Related Spring Batch Guides

Understand when to use Tasklet-based steps by exploring related Spring Batch concepts such as chunk processing, error handling, job flow control, and performance optimization.

🧱 Spring Batch Core Components

Learn how Tasklet fits into the broader Spring Batch architecture alongside JobRepository and StepExecutions.

🔄 ItemProcessor Example

Compare Tasklet-based processing with ItemProcessor-driven chunk-based batch jobs.

🚫 Skip Policy & Error Handling

Handle failures and exceptions safely. Learn how fault tolerance differs between Tasklets and Chunk steps.

🔁 Retry Mechanism

Implement retry logic for transient network or database errors occurring inside your batch executions.

🔀 Conditional Flow in Jobs

Control job execution paths based on Tasklet exit statuses. Branch your logic dynamically!

👂 JobExecutionListener

Track Tasklet execution outcomes using job and step lifecycle listeners to send completion emails.