Tasklet 방식을 이용한 배치 작업 예시
package spring.batch.fileCleanUp;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class LogGenerator {
private static final String ROOT_PATH = "./test-logs";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static void main(String[] args) throws IOException {
File dir = new File(ROOT_PATH);
if(!dir.exists()) {
dir.mkdirs(); // 현재 파일 아래에 test-logs 파일 생성
}
// 파일 이름에 날짜를 포함하여 생성 (2026.02.25.log)
createLogFile(dir, "access", 2); // 2일 전 // access.2026.02.23.log
createLogFile(dir, "access", 0); // 0일 전 = 금일 // access.2026.02.25.log
createLogFile(dir, "service", 50); // 50일 전 // access.2025.11.17.log
createLogFile(dir, "service", 100); // 100일 전 // access.2026.01.06.log
// 날짜 패턴이 없는 파일 생성, system_config.conf.log
createLogFile(dir, "system_config.conf", -1);
System.out.println("Finish to create test log " + ROOT_PATH);
}
private static void createLogFile(File dir, String prefix, int daysAgo) throws IOException {
String filename;
if (daysAgo == -1) {
// 날짜 패턴이 없는 일반 파일
filename = prefix;
} else {
// 날짜 패턴 적용: prefix_yyyy-MM-dd.log
LocalDate targetDate = LocalDate.now().minusDays(daysAgo);
String dateStr = targetDate.format(DATE_TIME_FORMATTER);
filename = prefix + "_" + dateStr + ".log";
}
File file = new File(dir, filename);
if (file.createNewFile()) {
System.out.println("create new file: " + filename);
} else {
System.out.println("already exists: " + filename);
}
}
}
실행 : test-logs 아래에 5개의 파일 생성

배치 Tasklet 생성
package spring.batch.fileCleanUp;
import lombok.RequiredArgsConstructor;
import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.StepContribution;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.infrastructure.repeat.RepeatStatus;
import java.io.File;
import java.time.LocalDate;
@RequiredArgsConstructor
public class FileCleanUpTasklet implements Tasklet {
private final String rootPath; // 파일을 삭제할 경로
private final int retentionDays; // 보관할 기간
@Override
public @Nullable RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
LocalDate cutOffDate = LocalDate.now().minusDays(retentionDays); // 현재 날짜 - 보관 기간
File folder = new File(rootPath);
File[] files = folder.listFiles();
if (files == null) return RepeatStatus.FINISHED; // 파일이 비어있다면 배치 작업 종료
for (File file : files) {
String name = file.getName();
if (name.endsWith(".log") && name.length() >= 10) { // 날짜가 적힌 파일 판단 : length >= 10
// "access_2026-01-31.log" => "2026-01-31"
name = name.substring(name.lastIndexOf("_") + 1, name.lastIndexOf("."));
LocalDate fileDate = LocalDate.parse(name);
if (fileDate.isBefore(cutOffDate)) {
file.delete();
System.out.println("삭제된 로그 파일 : " + name);
}
}
}
return RepeatStatus.FINISHED;
}
}
package spring.batch.fileCleanUp;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@RequiredArgsConstructor
public class FileCleanUpConfig {
private final JobRepository jobRepository;
private final PlatformTransactionManager txManager;
@Bean
public Tasklet fileCleanUpTasklet() {
return new FileCleanUpTasklet("./test-logs", 30); // 30일동안 보관
}
@Bean
public Job fileCleanUpJob() {
return new JobBuilder("fileCleanUpJob", jobRepository)
.start(fileCleanUpStep())
.build();
}
@Bean
public Step fileCleanUpStep() {
return new StepBuilder("fileCleanUpStep", jobRepository)
.tasklet(fileCleanUpTasklet(), txManager)
.build();
}
}
배치 작업 - fileCleanUpJob 실행
- 금일 날짜 - 30일 (retentionDays)보다 이전인 파일을 삭제
./gradlew bootRun --args='--spring.batch.job.name=fileCleanUpJob'

'Java & Spring > Batch' 카테고리의 다른 글
| [Spring] Batch 6 (0) | 2026.02.26 |
|---|---|
| [Spring] Batch 5 (0) | 2026.02.25 |
| [Spring] Batch 4 (0) | 2026.02.25 |
| [Spring] Batch 2 (0) | 2026.02.25 |
| [Spring] Batch 1 (0) | 2026.02.25 |