개요.

서비스 타입에 복수 개의 구현체를 만들어놓고 실행하는 와중에 IoC 컨테이너가 빈을 초기화하는 과정중에 발생한 에러에 대한 이야기.

 

설명.

보통 Service 레이어에 빈을 생성하기 위해서 일반적으로 아래와 같은 절차를 수행한다. 인터페이스를 만들고 하위 접미사에 "Impl" 을 사용하여 추상화된 메소드를 구현한다. 

  • Service ( interface )
    • ServiceImpl ( class )

하지만 하나의 서비스 인터페이스 내에 복수개의 서비스 빈을 만들어서 사용하고자 하는 경우는 어떻게 해야할까? 이미지를 저장해야하는 서비스가 있다고 한다면 클래스를 하위에 두 개로 구분할 수 있다.

  • ImageSaveService
    • ImageLocalSaveService
      서버 환경 내에 이미지를 저장로직을 수행한다.
    • ImageCloudSaveService
      클라우드 환경 내에 이미지 저장로직을 수행한다.

이 때 아래와 같은 코드를 작성하면 에러가 발생한다.

@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class ArticleCreateServiceImpl implements ArticleCreateService {

    private final ImageSaveService imageSaveService;
    
}

 

No qualifying bean of type available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: ~~

 

이미지를 저장하는 서비스에 롬복의 @RequiredArgsConstructor 를 이용하여 빈을 설정하면 위와 같은 에러가 발생된다. 왜냐하면 현재 같은 타입의 2개 이싱이고 이를 명확하게 묶을 수 있는@Qualifier 를 사용하여야 한다. 해당 주석을 통해서 Bean 객체의 이름을 지정할 수 있다.

 

이와 같은 문제는  @Qualifier(value = "ImageLocalSaveServiceImpl") 라는 구문을 위의 코드에 작성해주어야 한다.

  • @Qualifier ('타입이 맞는 빈 객체 이름")
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class ArticleCreateServiceImpl implements ArticleCreateService {

    @Qualifier(value = "ImageLocalSaveServiceImpl") @NonNull
    private final ImageSaveService imageSaveService;
    
}


@Service
@Qualifier("ImageCloudSaveServiceImpl")
public class ImageCloudSaveServiceImpl implements ImageSaveService {
}

@Service
@Qualifier("ImageLocalSaveServiceImpl")
public class ImageLocalSaveServiceImpl implements ImageSaveService {
}

 

Posted by doubler
,