• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

@Qualifier 질문드립니다.

22.11.13 03:31 작성 조회수 417

1

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]

안녕하세요. 다른 비슷한 질문이 있어서 보긴했는데 이해가 안되서 질문드립니다.

1. 애노테이션을 만들때, @Qualifier를 작성하지않고 애노테이션을 사용하게되면 에러가 발생하는데 왜 그런건가요? @Qualifier를 적어줌으로써 @Qualifier기능을 하는 애노테이션이다 라고 명시해주기위해 적어준건가요??

 

2. @Qualifier("mainDiscountPolicy")라고 하지않고@Qualifier나 @Qualifier()만 적어도 정상 동작하던데 왜 그런건가요? mainDiscountPolicy를 적으신 이유가 따로있을까요?

답변 1

답변을 작성해보세요.

2

OMG님의 프로필

OMG

2022.11.13

안녕하세요.gomdole03 님, 공식 서포터즈 OMG입니다.
.

1.
어노테이션을 만드는 이유와 @Qualifier의 동작에 대해 이해를 하지 못하신 것 같습니다.

우선 어노테이션을 만드는 이유는 아래와 같습니다.

"@Qualifier("mainDiscountPolicy") 이렇게 문자를 적으면 컴파일시 타입 체크가 안된다. 다음과 같은 애노테이션을 만들어서 문제를 해결할 수 있다."

@MainDiscountPolicy는 컴파일 시 타입체크를 하기 위함이지, @Qualifier의 동작을 포함하고 있지 않습니다. @Qualifier가 빠지면 그냥 그저그런 어노테이션 하나에 불과합니다.

@Qualifier는 빈 주입 시 식별하기 위함입니다. 식별하기 위해선 주입을 받는 빈과 주입되는 빈 끼리 Qualifier로 연결이 되어 있어야합니다.

@MainDiscountPolicy는 @Qualifier("식별이름")를 대체하기 위함입니다. 당연히

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MainDiscountPolicy {
}

@MainDiscountPolicy에 @Qualifier가 없으면 어떤 빈이랑 연결이 될지 알 수 없습니다.

imageimage

간단히 생각해서 동일한 타입의 빈이 있을 때(DiscountPolicy가 2개 이상일 때) @Qualifier("빈이름") 끼리 연결이 되어야 합니다.

 

2.

공식문서랑 여러 자료, @Qualifier 설명을 찾아봤는데 관련하여 내용은 못봤고, 코드로 확인해봤습니다.

MainDiscountPolicy와 상관없이 @Qualifier의 동작이므로 Qualifier로 확인하였는데,

@Qualifier로 이름 정의없이 추가하였고,

주입 받는 코드에서 @Qualifer를 사용, 주입 되는 코드에 특정 이름을 지정하면 찾을 수 없다고 식별할 수 없다고 출력되지만,

image이름 없는 Qualifier를 추가하면 해당 오류가 출력되지 않았습니다.

image

테스트 결과를 바탕으로 추론하면, 비어있는 문자열끼리 비교로 인해 매칭이되지 않나 싶습니다.

"".equals("") == true 가 되어서요.

image

정확한 근거가 될 수 있는 자료를 찾으면 좋았겠지만 못찾아서 테스트만 하여 아쉽지만,

아시는 분이 계시면 공유해주시면 감사하겠습니다.

 

.
감사합니다.

OMG님의 프로필

OMG

2022.11.13

공식문서에는 다음과 같은 설명이 있는데요,

여러 타입의 빈이 존재하지 않을 때 빈을 주입 받을 시 @Qualier로 지정된 클래스를 지정한다고 나와있기는 한데 개인적으로 와닿지는 않네요

 

image개인적인 생각은 영한님 말씀대로 @Qualifer는 찾는용도로 사용하고, 명시적으로 이름을 지정하는게 명확하여 개발 및 유지보수에 좋은 방법인 것 같습니다.

image

 

 

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core

 

gomdole03님의 프로필

gomdole03

질문자

2022.11.13

@MainDiscountPolicy는 컴파일 시 타입체크를 하기 위함이지, @Qualifier의 동작을 포함하고 있지 않습니다. @Qualifier가 빠지면 그냥 그저그런 어노테이션 하나에 불과합니다.

여기서,

1.@Qualifier의 동작을 포함하고있지않은데 왜 @Qualifier를 빼면 그저그런 어노테이션이 되는건가요??

2.그렇다면 왜 @MainDiscountPolicy는 @Qualifier의 역할을 하고있는건가요? 어노테이션을 만들때 @Qualifier를 적어줘서 그런거 아닌가요??

3.@Target~@Documented를 적은이유가 @Qualifier과 동일한 역할을 하기위해 적은건가요?? 그렇다면 @Qualifier(“MainDiscountPolicy")를 왜 적어야하는지 질문드립니다..

OMG님의 프로필

OMG

2022.11.13

1.@Qualifier의 동작을 포함하고있지않은데 왜 @Qualifier를 빼면 그저그런 어노테이션이 되는건가요??

=> @MainDiscountPolicy 어노테이션에서 @Qualifier를 빼면 식별을 위한 @Qualifier를 뺀 어노테이션 아닌가요?

@MainDiscountPolicy 대신 다른 임의의 이름을 가진 어노테이션과 무슨 차이가 있을것이라 생각하는지 역으로 궁금하네요.

2.

그렇다면 왜 @MainDiscountPolicy는 @Qualifier의 역할을 하고있는건가요? 어노테이션을 만들때 @Qualifier를 적어줘서 그런거 아닌가요??

=> 네 맞습니다.

3.

왜 써야 되는지에 대한 이유는 강의와 답변에도 있습니다.

@Target~@Documented 이 부분에 대한 이해가 부족하신 것이라면, 본 강의 선수지식에 해당하는 자바 기본 지식에 해당하여 학습하시고 나서 다시 질문을 남겨주시면 좋을 것같아요. 

지금 당장 이해가 안되고 혼선이 있다면 @Qualifier의 기능에만 초점을 맞추시고 본 강의 완강 후 어노테이션에 대한 학습과 본강의 복습 하고 나서 다시 보시길 권장드려요 :)

 

OMG님의 프로필

OMG

2022.11.13

@MainDiscountPolicy는 컴파일 시 타입체크를 하기 위함이지, @Qualifier의 동작을 포함하고 있지 않습니다. @Qualifier가 빠지면 그냥 그저그런 어노테이션 하나에 불과합니다.

 

다시 풀어서 설명 드리면

@MainDiscountPolicy는 컴파일 시 타입체크를 하기 위함이지,

-> 이 내용은 @MainDiscountPolicy에 @Qualifier가 포함된 상태에서를 얘기하는 것입니다.

@Qualifier의 동작을 포함하고 있지 않습니다. @Qualifier가 빠지면 그냥 그저그런 어노테이션 하나에 불과합니다.

=> @MainDiscountPolicy는 @Qualifier("mainDiscountPolicy")가 @MainDiscountPolicy안에 포함되어 있어야지만 의미가 있는 어노테이션이 됩니다.

image

어노테이션 코드 위에 있는 @Target~@Documented 어노테이션은 어노테이션을 작성할 때 사용하는 코드이지, @Qualifer가 가진 기능(= 동일한 타입의 빈을 식별)을 포함하진 않습니다. 그렇기 때문에 "그저그런" 이라는 표현을 한것이구요.

 

 

OMG님의 프로필

OMG

2022.11.13

추가적으로 궁금한 사항이 있으실 경우, 강의 내용과 코드를 기반으로 왜 그렇게 생각하는지 조금 더 구체적으로 설명해주시면 답변 드리기에 좋을 것 같아요.

 

gomdole03님의 프로필

gomdole03

질문자

2022.11.13

제가 이해한 바가 맞는지 확인 부탁드립니다.

  1. @Target~@Documented 어노테이션은 어노테이션을 작성할때 사용하는 코드이다.

  2. @Qualifier를 적은 이유는 @Qualifier가 가진 기능(=동일한 타입의 빈을 식별)을 포함해주기 위해서 적은것이다.

 

추가로 질문드립니다.

  1. 애노테이션을 만드는 코드에서@Qualifier를 적을때 단순히 @Qualifier나 @Qualifier() 라고 적지않고, @Qualifier("mainDiscountPolicy") 라고 적어야하는 이유가 있나요? 테스트를 해보니 @Qualifier나 @Qualifier() 라고 적어서 애노테이션을 만들어도 에러없이 동작하는거같은데 왜 어노테이션을 만들때 @Qualifier나 @Qualifier() 라고 적지않고, @Qualifier("mainDiscountPolicy") 라고 mainDiscountPolicy를 적어줘야하는지 궁금합니다.

OMG님의 프로필

OMG

2022.11.13

1,2번 맞습니다.

3번은 본 강의에서는 "할인정책" 하나의 케이스에만 예제로서 설명이 되어있지만, 할인정책 뿐만 아니라 @Qualifer를 사용해야하는 다양한 상황을 가정한다면 이를 명확하게 명시적으로 보여주는게 개발과 유지보수에 용이하다 생각합니다.

 

 

 

gomdole03님의 프로필

gomdole03

질문자

2022.11.13

친절한 설명 감사드립니다.

그럼 어노테이션을 만들때 @Qualifier나 @Qualifier() 라고 적지않고, @Qualifier("mainDiscountPolicy") 라고 mainDiscountPolicy를 명시적으로 적은 이유는,

이 코드에서는 @Qualifier나 @Qualifier() 라고 적어도 상관은 없지만 나중에 개발과 유지보수를 하게되면 @MainDiscountPolicy가 어떤 어노테이션인지 까볼때? @Qualifier기능을 하는 어노테션이고, 할인정책(=mainDiscountPolicy)에 관한 @Qualifier기능을 하는 어노테이션이구나 라고 알수있도록@Qualifier("mainDiscountPolicy") 라고 적어준것이다

이렇게 이해하면 될까요?

OMG님의 프로필

OMG

2022.11.13

네, 잘 정리하신 것 같습니다. 남겨주신 댓글의 의도로 설명드린 게 맞습니다.