commit
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
package com.spring.infra.batch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.launch.support.RunIdIncrementer;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
/**
|
||||
* 배치 작업을 정의하는 추상 클래스입니다.
|
||||
* <p>
|
||||
* 이 클래스는 배치 작업의 기본 설정 및 실행을 관리합니다.
|
||||
* </p>
|
||||
*
|
||||
* @author mindol
|
||||
* @version 1.0
|
||||
*/
|
||||
@Configuration
|
||||
public abstract class AbstractBatchTask implements ApplicationContextAware {
|
||||
|
||||
private final BatchJobInfo batchJobInfo;
|
||||
private ApplicationContext applicationContext;
|
||||
private JobRepository jobRepository;
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
/**
|
||||
* 기본 생성자입니다.
|
||||
* <p>
|
||||
* BatchJobInfo 어노테이션을 찾고, 없으면 예외를 발생시킵니다.
|
||||
* </p>
|
||||
*/
|
||||
protected AbstractBatchTask() {
|
||||
this.batchJobInfo = AnnotationUtils.findAnnotation(getClass(), BatchJobInfo.class);
|
||||
if (this.batchJobInfo == null) {
|
||||
throw new IllegalStateException("BatchJobInfo annotation is missing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ApplicationContext를 설정합니다.
|
||||
*
|
||||
* @param applicationContext 설정할 ApplicationContext
|
||||
* @throws BeansException Beans 예외
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
registerJobBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치 작업을 Spring의 Bean으로 등록합니다.
|
||||
*/
|
||||
private void registerJobBean() {
|
||||
var beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
|
||||
var registry = (BeanDefinitionRegistry) beanFactory;
|
||||
var beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Job.class, this::createJob);
|
||||
registry.registerBeanDefinition(jobName(), beanDefinitionBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
/**
|
||||
* JobRepository를 설정합니다.
|
||||
*
|
||||
* @param jobRepository 설정할 JobRepository
|
||||
*/
|
||||
@Autowired
|
||||
public void setJobRepository(JobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* PlatformTransactionManager를 설정합니다.
|
||||
*
|
||||
* @param transactionManager 설정할 PlatformTransactionManager
|
||||
*/
|
||||
@Autowired
|
||||
public void setTransactionManager(PlatformTransactionManager transactionManager) {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치 작업을 생성합니다.
|
||||
*
|
||||
* @return 생성된 Job 객체
|
||||
* @throws IllegalStateException STEP이 정의되지 않은 경우 예외 발생
|
||||
*/
|
||||
private Job createJob() {
|
||||
List<Step> steps = createSteps();
|
||||
if (steps.isEmpty()) {
|
||||
throw new IllegalStateException("No steps defined for job: " + jobName());
|
||||
}
|
||||
var jobBuilder = new JobBuilder(jobName())
|
||||
.incrementer(new RunIdIncrementer())
|
||||
.repository(jobRepository)
|
||||
.start(steps.get(0));
|
||||
for (int i = 1; i < steps.size(); i++) {
|
||||
jobBuilder = jobBuilder.next(steps.get(i));
|
||||
}
|
||||
return jobBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치 작업의 STEP을 생성합니다.
|
||||
*
|
||||
* @return 생성된 Step 리스트
|
||||
*/
|
||||
protected List<Step> createSteps() {
|
||||
List<Step> steps = new ArrayList<>();
|
||||
steps.add(addStep(jobName() + "Step", createTasklet()));
|
||||
return steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP을 추가합니다.
|
||||
*
|
||||
* @param stepName STEP의 이름
|
||||
* @param tasklet STEP에서 실행할 Tasklet
|
||||
* @return 생성된 Step 객체
|
||||
*/
|
||||
protected Step addStep(String stepName, Tasklet tasklet) {
|
||||
return new StepBuilder(stepName)
|
||||
.repository(jobRepository)
|
||||
.transactionManager(transactionManager)
|
||||
.tasklet(tasklet)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 서브클래스에서 구현해야 하는 Tasklet을 생성합니다.
|
||||
*
|
||||
* @return 생성된 Tasklet 객체
|
||||
*/
|
||||
protected abstract Tasklet createTasklet();
|
||||
|
||||
/**
|
||||
* 배치 작업 그룹을 반환합니다.
|
||||
*
|
||||
* @return 배치 작업 그룹 이름
|
||||
*/
|
||||
public String group() {
|
||||
return batchJobInfo.group();
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치 작업 이름을 반환합니다.
|
||||
*
|
||||
* @return 배치 작업 이름
|
||||
*/
|
||||
public String jobName() {
|
||||
return batchJobInfo.jobName();
|
||||
}
|
||||
|
||||
/**
|
||||
* cron 표현식을 반환합니다.
|
||||
*
|
||||
* @return cron 표현식
|
||||
*/
|
||||
public String cronExpression() {
|
||||
return batchJobInfo.cronExpression();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user