베어_
TechBear
베어_
전체 방문자
오늘
어제
  • 분류 전체보기 (336)
    • Spring (33)
      • 개념 (13)
      • Security (5)
      • 실습 (1)
      • 토비 스프링 (11)
    • JPA (6)
    • 프로젝트 기록 (24)
    • DB (13)
    • JAVA (18)
    • 알고리즘 (50)
      • 유형정리 (8)
      • Baekjoon (21)
      • LeetCode (18)
    • 디자인패턴 (0)
    • 개발서적 (79)
      • Effective Java (78)
      • 객체지향의 사실과 오해 (1)
    • 독후감 (4)
    • 보안 (2)
    • 운영체제(OS) (53)
      • 공룡책 (53)
    • 컴퓨터 네트워크 (28)
      • 컴퓨터 네트워크 하향식 접근 (23)
    • 자료구조 (1)
    • DevOps (2)
    • 앱 개발 (20)
      • 안드로이드 스튜디오 (20)

블로그 메뉴

    공지사항

    인기 글

    태그

    • 데이터베이스
    • Spring
    • 함수형인터페이스
    • 토비스프링
    • 자바8
    • 백준
    • 스프링시큐리티
    • C++
    • 스프링
    • 스레드
    • 운영체제
    • 자바
    • 코드업
    • java
    • leetcode
    • jpa
    • 이펙티브자바
    • 알고리즘
    • BFS
    • dfs

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    베어_

    TechBear

    [Spring] 의존성 주입과 동일 타입 클래스 문제 해결
    Spring/개념

    [Spring] 의존성 주입과 동일 타입 클래스 문제 해결

    2022. 4. 5. 00:15

    의존성 주입을 위해 필드 주입, setter주입, 생성자 주입 등 여러 가지 방법을 이용할 수 있다. 하지만, 프로그램에서 한 번 의존성을 셋팅하고 나면 바꿀 일이 없기 때문에 생성자 주입 방법이 권장된다.

     

    의존성 주입

       다음과 같이 NoteService에서 NoteRepository를 필요로 한다고 가정해보자. 이런 경우 생성자 또는 setter를 이용하여 noteRepository의 실제 객체를 주입 받아야 한다. 이런 것을 의존성 주입이라고 한다.

    public class NoteService {
        
        private NoteRepository noteRepository;
    
        public NoteService(NoteRepository noteRepository) {
            this.noteRepository = noteRepository;
        }
    }

     

    스프링에서는 이런 의존성을 스프링 컨테이너가 관리해준다.

     

    @Autowired

       스프링에서는 의존성 주입을 위해 @Autowired라는 어노테이션이 이용된다. 이 어노테이션은 일반적으로 타입을 기준으로 주입을 받는다.

    @Service
    public class NoteService {
    
        @Autowired
        NoteRepository noteRepository;
    }

     

    타입을 기준으로 의존성을 주입받기 때문에 다음과 같이 인터페이스를 구현하고 있는 2개 이상의 구현 클래스가 있을 때 문제가 발생할 수 있다.

    @Repository
    public interface NoteRepository {}
    
    @Repository
    public class NoteA implements NoteRepository{}
    
    @Repository
    public class NoteB implements NoteRepository {}
    
    @Service
    public class NoteService {
    
        @Autowired
        NoteRepository noteRepository;
    }

     

    위의 코드를 작성하고 실행하면, 의존성 주입 과정에서 2개의 싱글톤 빈이 발견되어 주입을 할 수 없다고 나온다. 

     

    동일 타입 클래스 문제를 해결하는 방법

    1. @Autowired

       먼저 Autowired는 타입 매칭을 시도하고, 빈이 여러개가 있으면 필드 이름, 파라미터 이름으로 빈을 추가 매칭한다.

    @Autowired
    private DiscountPolicy discountPolicy
    ------- 수정 후 -------
    
    @Autowired
    private DiscountPolicy rateDiscountPolicy

    이 경우 필드명이 rateDiscountPolicy이므로 rateDiscountPolicy가 정상 주입된다.

     

    2. @Primary

       우선순위를 정하는 방법으로 여러 빈이 매칭되면 @Primary가 우선권을 가진다. 

    @Repository
    @Primary
    public class NoteA implements NoteRepository{}

     

    3. @Qualifier

       추가 구분자를 붙여주는 방법으로, 주입시 추가적인 정보를 제공하는 것이지 빈 이름을 변경하지는 않는다.

    @Component
    @Qualifier("mainDiscountPolicy")
    public class RateDiscountPolicy implements DiscountPolicy() {
        @Autowired
        public OrderServiceImpl(MemberRepository memberRepository,
            @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
                this.memberRepository = memberRepository;
                this.discountPolicy = discountPolicy;
        }
    }

    만약 @Qualifier("mainDiscountPolicy")를 찾지 못하면, mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다. 만약 빈도 없으면 예외가 발생한다. 

     

    -------------

    @Autowired를 사용한 의존성 주입의 경우, 빈 객체가 없으면 에러가 난다. 이 때 해결하는 방법을 옵션 처리에서 알아보자.

      'Spring/개념' 카테고리의 다른 글
      • [Spring] 리다이렉트 동작 원리
      • [Spring] Validation
      • [Spring] 스프링 빈 콜백
      • [Spring] 자동 주입 대상이 2개 이상일 때
      베어_
      베어_
      Today I learned | 문제를 해결하는 개발자

      티스토리툴바