이번 스프링부트 프로젝트에서 인터페이스의 구현체를 선택해서 주입해야하는 부분이 있었다. 구현체를 주입하는건 간단하고 다양한 방법이 존재하지만, 스프링 빈 주입시 어떤 구현체를 주입할지 명확하게 지정할 수 있도록 해주는 @Qualifier
애너테이션을 적용해보기로 하였다.
@Service
@RequiredArgsConstructor
public class AgentMatchingService {
private final ApplicationEventPublisher eventPublisher;
@Qualifier("leastBusy")
private final AgentMatchingStrategy strategy;
}
@Component("leastBusy")
public class LeastBusyStrategy implements AgentMatchingStrategy {
}
처음엔 이런식으로 구현했다.
그런데 @Qualifier
로 지정한 구현체가 주입되지 않는 문제가 발생했다.
문제의 원인은 롬복 생성자 때문이었다. 롬복의 자동 생성 기능 (@AllArgsConstructor
, @RequiredArgsConstructor
등)은 단순히 생성자를 자동 생성할 뿐, 필드에 붙어있는 @Qualifier
를 인식해서 주입되는 파라미터에 붙이지 못한다.
가장 명확하고 빠른 해결 방법으로는 롬복의 생성자를 사용하지 않고 그냥 직접 생성자를 정의하면 된다.
public AgentMatchingService(
ApplicationEventPublisher eventPublisher,
@Qualifier("leastBusy") AgentMatchingStrategy strategy)
{
this.eventPublisher = eventPublisher;
this.strategy = strategy;
}
이 방법은 구글링하다가 찾은 방법인데 롬복의 설정 파일을 추가해 @Qualifier
를 인식하도록 하는 방법도 있다고 한다.
루트 디렉토리에 lombok.config
파일을 생성하고 아래의 내용을 추가한다.
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
다만 이 방법을 적용하지 않은 이유는, 우리 프로젝트는 멀티 모듈로 구성된 MSA 프로젝트이므로 설정 파일을 추가하는 것보단 명시적으로 생성자를 사용하는게 더 간단하고 안정적인 해결 방법이라 생각했기 때문이다.