본문 바로가기
IT 공부/자바와 웹 애플리케이션

[lombok] - @RequiredArgsContructor와 @Qualifier 같이 쓰는 원리

by exdus3156 2024. 1. 6.

스프링 프로젝트에서 @Qualifier 어노테이션을 통해 원하는 빈(bean)의 이름을 특정해 주입받을 수 있다. 그러나 롬복과 함께 사용하기 위해서는 클래스패스에 아래의 lombok.config 파일을 아래처럼 설정해야 비로소 제대로 스프링이 의존성을 주입해줄 수 있다.

lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier

이 포스팅은 위 파일을 사용해야 하는 이유에 대한 것이다.

 


1. 생성자 통해 의존성 주입 받기

스프링 프레임워크 사용 시, 일반적으로 생성자를 통해 의존성을 주입받는다. 필드 주입과 세터 주입은 각각의 단점이 명확하기 때문에 잘 사용되진 않는다.

생성자를 통해 의존성을 주입받기 위해서는 기본적으로 아래와 같은 형태로 사용되어야 한다.

public class Test {
    private SampleA a;
    private SampelB b;
    
    @Autowired
    public Test(SampleA a, SampleB b) {
    	this.a = a;
        this.b = b;
    }
}

 

만약 특정 빈의 이름을 명시해서 구체적으로 주입받고자 하는 객체를 선택하려면 @Qualifier를 사용해야 한다. 그 형태는 아래와 같아야 한다.

public class Test {
    private Sample sample;
    
    public Test( @Qulifier("a") Sample sample ) {
        this.sample = sample;
    }
}

인자로 여러 개의 객체가 올 수 있으므로 인자 앞에 직접적으로 붙여서 구체적인 빈을 명시해야 하는 것이다.

 


2. 롬복과 함께 사용 시 주의점

우리가 롬복을 사용하는 이유는 코드 작성을 최대한 줄이기 위해서다. 생성자 코드는 굉장히 번거로운 작업이기 때문에 롬복은 자체적으로 생성자 코드 또한 만들어준다.

많은 어노테이션이 있지만, 특히 @RequiredArgsConstructor 어노테이션은 final이 붙은 필드에 대해 생성자 코드를 만들어준다.

@RequiredArgsConstructor
public class Test {
    private final int dataA;
    private final int dataB;
    
    // 아래의 코드가 자동 생성된다. @Qualifier가 붙지 않았다.
    public Test(int dataA, int dataB) {
        this.dataA = dataA;
        this.dataB = dataB;
    }
}

 

문제는 생성자로 @Qualifier를 사용하기 위해선 생성자의 인자 앞에 어노테이션이 붙어야 한다는 점이다. 그런데 @RequiredArgsContructor 사용 시 롬복이 이러한 조건을 모르므로 문제가 발생한다.

@RequiredArgsConstructor
pubilc class Test {
    @Qulifier("a")
    private final int data;
    
    // 롬복에 의해 아래의 코드가 생성된다.
    public Test(int data) {
        this.data = data;
    }
}

롬복에 의해 생성된 코드를 보자. 인자 앞에 @Qualifer가 붙지 않았다. 롬복은 기본적으로 스프링과는 완전히 별개의 라이브러리일 뿐이다. 따라서 @Qualifier가 필드에 붙었다고 한들, 그것을 딱히 고려하지 않고 순수한 생성자 코드를 편집해줄 뿐이다.

어노테이션이 인자 앞에 붙지 않기 때문에 스프링은 생성자로 의존성을 주입해줄 수 없는 것이다.

 

lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier

위 lombok.config 파일의 의미는 어노테이션을 만들 때 인자에 위 어노테이션이 붙으면 그것도 전부 새로운 코드에 복사하라는 뜻이다. 따라서 이 설정이 있으면 위 코드는 롬복에 의해 아래와 같이 번역된다.

@RequiredArgsConstructor
public class Test {
    @Qualifer("a")
    private final int data;
    
    // 롬복에 의해 아래의 코드가 생성된다.
    public Test( @Qualifier("a") int data ) {
        this.data = data;
    }
}

즉, 롬복이 코드를 생성할 때 필드에 붙은 어노테이션 중 Qualifier는 새로운 코드에도 붙이라는 뜻이다. 그래서 위와 같이 편집될 수 있는 것이다.

이제 @Qualifier와 롬복을 함께 사용할 때 lombok.config를 설정해야 하는 이유를 알게 되었을 것이다.