인프런 커뮤니티 질문&답변

다온님의 프로필 이미지

작성한 질문수

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

20강과 21강을 듣고 질문드립니다!

해결된 질문

23.02.17 02:06 작성

·

276

·

수정됨

2

안녕하세요, 우선 좋은 강의 만들어주셔서 너무 잘 듣고 있습니다.

Spring 어노테이션의 의미를 대략은 알고 있었지만 자세히 알지 못하고 사용했던 것 같은데, 강의를 들으면서 하나씩 정리되어 가는 기분을 느끼고 있어서 많이 배우고 있습니다.

듣다가 궁금한 점이 생겨서 부족한 질문이지만 남겨보게 되었습니다!

 

  1. 21강에서 설명해주신 Configuration + Bean 조합과 Component의 어노테이션 차이가 있을까요? 개발자가 직접 만든 클래스를 스프링 빈을 만들어줄 때 사용해주는 것으로 이해해서 같은 역할인 것 같은데 어떤 차이가 있을까? 라는 생각이 들었습니다.

  2. 20강에서 설명해주신 @Primary, 그리고 21강에서 설명해주신 @Qualifier는 모두 스프링에서 여러 선택지가 있어서 선택하기 어려울 때 이게 우선순위야! 라고 알려주는 개념으로 이해하였는데요. 그럼 이 두가지도 같은 역할을 하는 것 같은데 어떤 차이가 있을까? 가 궁금해졌습니다. 직접 지정해주는 @Qualifier가 우선순위는 더 높지만, 두가지 다 사용하면 개인적으로는 버그가 있을 때 디버깅을 하기 어려워질 것 같은데 두가지 다 사용하는 경우도 있나요? (제가 현업에서 아직 경험해보지 못했을 수도 있을 것 같습니다 ^^;)

 

답변해주시면 많은 도움이 될 것 같습니다! 좋은 강의 만들어주셔서 감사드립니다 🙏🏻

답변 1

1

최태현님의 프로필 이미지
최태현
지식공유자

2023. 02. 17. 23:43

안녕하세요 다온님!! 아이고~~ 좋게 봐주셔서 너무 감사드립니다! 😊😊

 

질문 주신 내용 차근차근 답변 드려볼게요!!!

 

[1. @Configuration + @Bean과 @Component의 차이]

결론부터 말씀드리면, 기능적인 차이는 없습니다!!!

  • @Component : 개발자가 직접 만든 클래스에 사용

  • @Configuration + Bean : 외부 라이브러리나 프레임워크의 클래스를 등록할 때 사용

으로 나눠진 이유는, "외부 라이브러리나 프레임워크의 클래스"에 저희가 직접 @Component 어노테이션을 붙일 수 없기 때문입니다.

그러니 외부 라이브러리, 프레임워크의 클래스를 빈으로 등록하려면 무조건 @Configuration + @Bean을 사용해야 하는 것이죠!

 

그렇다면 이렇게 생각하실 수도 있습니다. 엇 개발자가 직접 만든 클래스도 Configuration + Bean 를 사용하면 안되나?!! 매우 좋은 포인트이신데요~~~

일반적으로는 관례상 Component를 붙여주는 편입니다. 그 이유는 제가 직접 만들었으니 1) @Component 어노테이션을 붙일 수 있고, 2) @Configuration + @Bean 조합을 사용하는것보다 @Component 어노테이션을 하나 붙이는게 더 간결하기 때문입니다.

물론 절대적인 기준은 아니라서 간혹~ 직접 만든 클래스에도 @Configuration + @Bean 조합 쓰곤 합니다!

 

 

[2. @Primary와 @Qualifer는 어떤 차이가 있는가?]

이렇게 생각하시면 쉽습니다!!!

제가 어떤 빈을 주입하려고 하는데 후보가 3개 있습니다. 코드로 간단히 표현해보면 아래와 같습니다.

public interface AService { }

@Service
public class AService1 implements AService { }

@Service
public class AService2 implements AService { }

@Service
public class AService3 implements AService { }

이중에 AService1 이 가장 기본이라고 생각하면 @Primary 를 붙여줄 수 있습니다.

@Primary
@Service
public class AService1 implements AService { }

매우 좋습니다~ 여기까진 문제가 없어요!! AService 를 주입 받으려 하면 가장 기본이 되는 AService1 가 잘 들어갈겁니다~

 

그런데 말이죠~ 이제 AService를 사용하는 100가지 코드에서 99가지 경우는 AService1 을 사용하면 되는데 1가지 경우에 AService2 를 쓰려고 합니다.

어떻게 하면 좋을까요?!!

이럴 때 바로 @Qualifier 가 필요합니다.

@Service
public class Service100 { // Service1 부터 Service100까지 있다고 하겠습니다 ㅎㅎㅎ

  private final AService aService;

  public OOOOService(@Qualifier("aService2") AService aService) {
    this.aService = aService;
  }

}

여기서는 @Qualifier 를 사용해서 AService2 를 사용하겠다고 직접 명시 해주어야만 AService2 를 사용할 수 있습니다.

이런 경우가 바로, @Primary@Qualifier를 둘 다 사용하는 경우입니다.

 

이렇게 되면 Service1 ~ Service99까지는 AService1을 사용하고 Service100만 ASerivce2를 사용하는 것이 명확하니 디버깅이 그렇게 어렵지는 않습니다.

물론! 제가 개발을 몇년간 하면서도 @Primary@Qualifier를 둘 다 쓰는 경우는 꽤 드물긴 했습니다 ㅎㅎㅎ 그래도 여러 빈 설정을 복잡하게 해줄 때 간혹 사용하는 편이에요!

 

제 답변이 도움이 되었으면 좋겠네요!

혹시나 또 궁금하신 점 생기시면 편하게 질문 남겨주세요! 감사합니!! 🙏🙏

다온님의 프로필 이미지
다온
질문자

2023. 02. 18. 00:43

상세한 예시까지 들어주셔서 차이점에 대해 명확히 이해되었어요. 답변 감사합니다!

다온님의 프로필 이미지

작성한 질문수

질문하기