Job별 Bean등록하기

스프링배치에서 여러개의 Job을 생성하다보니, 동일한 Bean에 대한 충돌 오류가 계속해서 발생했다.

@RequiredArgsConstructor
@Configuration
public class JpaCursorCustomerJob {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final EntityManagerFactory entityManagerFactory;

    @Bean
    public Job  job(){
        return jobBuilderFactory.get("jpaCursorItemReaderJob")
                .start(jpaCursorItemReaderStep())
                .build();
    }
@RequiredArgsConstructor
@Configuration
public class HibernateCursorCustomerJob {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final EntityManagerFactory entityManagerFactory;

    @Bean
    public Job job() {
        return jobBuilderFactory.get("hibernateCursorItemReaderJob")
                .start(hibernateCursorItemReaderStep())
                .build();
    }

application.yml에 bean overriding을 허용하도록 할 수도 있지만,

해당 빈들이 모두 등록될 필요가 없기때문에 수행할 job.name을 가진 실제로 수행할 Job의 Bean만 등록하고 싶어 @ConditionalOnProperty 어노테이션을 사용할 것이다.

@ConditionalOnProperty란?

application.properties or application.yml의 속성 값에 따라 조건부로 일부 빈을 생성 해야하는 경우에만 생성 가능하게 해준다.

스프링 배치에서 다음과 같이 수행할 Job이름을 받아올 때 Job 이름에 해당하는 Class의 빈만 등록하도록 하려고 할때,

각각 Job 이름에 따라 등록하도록 설정 하였다. 여기서 name은 프로퍼티 key값이며, havingValue에 포함된 값인 경우에만 조건부로 빈을 등록하겠다는 것이다.

위와 같이 설정하여 --job.name=hibernateCursorItemReaderJob city=Chicago로 수행하면

JpaCursorCustomerJob는 job.name이 다르므로 빈 등록에서 제외되고, HibernateCursorCustomerJob는 일치하여 빈 등록이 된것을 확인할 수 있다.

하지만 여기서 문제가 발생했다.

No job found in registry for job name: hibernateCursorItemReaderJob 해당 job이름을 찾을 수 없다는 로그가 찍혔고 다음과 같이 조건부로 빈을 설정하면 JobRegistry에 등록이 안되는 것이다.

별도로 등록한 Bean JobRegistry에 등록하기

두가지 방법으로 해결할 수 있다.

1. Job을 Bean으로 등록하기전 JobRegistry에 등록

다음과 같이 jobRegistry에 등록해주면 되지만, Job Bean 선언마다 등록해줘야하는 단점이 있다.

2. JobRegistryBeanPostProcessor 활용하기

BatchConfigurer를 하나 생성하여 JobRegistryBeanPostProcessor를 등록해줄것이다.

JobRegistryBeanPostProcessor는 Job마다 등록할 필요 없이 Job이 빈으로 등록될 때 후처리를 통해 JobRegistry에 등록해준다.

매번 Job을 등록할때마다 선언을 해줘야하는 1번방법보다 기본 BatchConfigurer를 하나 생성해주고, 해당 BatchConfigurer@Import하는 방법으로 해결할 것이다.

해당 Job을 수행하면 정상적으로 수행되는 것을 확인할 수 있다.

참고

Last updated

Was this helpful?