지난 시간에 스프링 부트가 DefaultBatchConfiguration
를 통해 JobLauncherApplicationRunner
빈을 등록하고
JobLauncher
의 run()
메서드를 호출하는 과정을 살펴보았습니다.
이번 시간에는 간단하게 JobRunner
부터 시작하여 Job
의 execute
가 실행되는 부분까지, 간단히 정리해보며
잡의 생명주기를 다시 따라가 보겠습니다.
JobRunner: JobLauncherApplicationRunner -> JobLauncher 과정
스프링 배치를 실행할 때
JobRunner
를 사용하긴 하지만,JobRunner
는 프레임워크가 제공하는 표준 모듈은 아닙니다.
각 시나리오마다 서로 다른 구현체가 필요하기 때문에 스프링 배치는JobRunner
라는 인터페이스를 별도로 제공하지 않습니다.
JobLauncherApplicationRunner
에서
protected void execute(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException,
JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
JobParameters parameters = getNextJobParameters(job, jobParameters);
JobExecution execution = this.jobLauncher.run(job, parameters);
if (this.publisher != null) {
this.publisher.publishEvent(new JobExecutionEvent(execution));
}
}
위와 같이 JobLauncher
의 run()
메서드를 실행합니다.
@Configuration(proxyBeanMethods = false)
@Import(ScopeConfiguration.class)
public class DefaultBatchConfiguration implements ApplicationContextAware {
...
@Bean
public JobLauncher jobLauncher() throws BatchConfigurationException {
TaskExecutorJobLauncher taskExecutorJobLauncher = new TaskExecutorJobLauncher();
taskExecutorJobLauncher.setJobRepository(jobRepository());
taskExecutorJobLauncher.setTaskExecutor(getTaskExecutor());
try {
taskExecutorJobLauncher.afterPropertiesSet();
return taskExecutorJobLauncher;
}
catch (Exception e) {
throw new BatchConfigurationException("Unable to configure the default job launcher", e);
}
...
/**
* Return the {@link TaskExecutor} to use in the the job launcher. Defaults to
* {@link SyncTaskExecutor}.
* @return the {@link TaskExecutor} to use in the the job launcher.
*/
protected TaskExecutor getTaskExecutor() {
return new SyncTaskExecutor();
}
}
v5부터 생겨난 기본 설정 클래스인 DefaultBatchConfiguration
에서 JobLauncher
를 빈으로 등록해줍니다.
또한 JobLauncher
는 org.springframework.core.task
의 TaskExecutor
에 대한 의존성이 있는데, 이것도 같은 클래스에서 생성해줍니다.
기본값은 SyncTaskExecutor
입니다.
이 경우엔 Job
은 JobLauncher
와 동일한 스레드에서 실행되게 됩니다.
getter를 오버라이딩하면 비동기 TaskExecutor도 사용할 수 있습니다.
이러면 Job
이 JobLauncher
와 다른 스레드에서 실행 될 것입니다.
JobLauncher: TaskExecutorJobLauncher -> TaskExecutor: SyncTaskExecutor 과정
public class TaskExecutorJobLauncher extends SimpleJobLauncher {
@Override
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException,
JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
return super.run(job, jobParameters);
}
TaskExecutorJobLauncher
는 곧 삭제될 Deprecate 된 SimpleJobLauncher
를 확장하고 있습니다.
run()
메서드에서 곧바로 SimpleJobLauncher
의 run()
을 호출합니다.
@Deprecated(since = "5.0.0", forRemoval = true)
public class SimpleJobLauncher implements JobLauncher, InitializingBean {
@Override
public JobExecution run(final Job job, final JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
JobParametersInvalidException {
...
try {
taskExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (logger.isInfoEnabled()) {
logger.info("Job: [" + job + "] launched with the following parameters: [" + jobParameters
+ "]");
}
job.execute(jobExecution);
...
SimpleJobLauncher
는 run()
메서드에서 TaskExecutor
를 통해 Runnable
을 실행합니다.
그리고 그 안에서 Job
의 execute()
메서드가 호출됩니다.
JobRunner
(JobLauncherApplicationRunner
)에서 JobLauncher
의 run(잡, 파라미터)
를 호출한다.
JobLauncher
(TaskExecutorJobLauncher
)에서는 TaskExecutor
의 execute(Runnable)
을 호출한다.
TaskExecutor
(SyncTaskExecutor
)는 오버라이딩 된 Runnable
의 run()
메서드를 실행하면서 Job
의 execute()
를 호출한다.
JobRunner
-> JobLauncher
-> TaskExecutor
-> Job