조회 빈이 2개 이상일 때 선택 방법, 자동 빈 등록 vs 수동 빈 등록

inhalin·2022년 7월 24일
0

김영한님의 스프링 핵심 원리 - 기본편 강의를 듣고 정리한 내용입니다.

조회 빈이 2개 이상일 때

@Autowired는 먼저 타입이 같은 빈을 선택한다. 그런데 타입이 같은 빈이 2개가 조회되는 경우가 생길 수 있다. 이런 경우에는 여러가지 방법으로 등록할 빈을 선택할 수 있다. 아래 코드와 같은 경우에 어떤 방법으로 등록할 빈을 선택할 수 있는지 확인해보자.

  • 빈 등록
@Component
public class MemoryMemberRepository implements MemberRepository{}

@Component
public class DemoMemberRepository implements MemberRepository{}
  • 의존관계 주입
@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

등록할 빈을 선택하는 여러가지 방법

1. 필드명이 같은 빈이 자동으로 등록된다.

@Autowired
private MemberRepository memoryMemberRepository; // memoryMemberRepository가 등록됨

2. @Qualifier로 추가구분자를 붙여서 등록할 빈을 찾는다.

@Component
@Qualifier("mainMemberRepo")
public class MemoryMemberRepository implements MemberRepository{}

@Component
@Qualifier("demoMemberRepo")
public class DemoMemberRepository implements MemberRepository{}
@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberServiceImpl(@Qualifier("mainMemberRepo")  MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

3. @Primary로 등록할 빈의 우선순위를 정해준다.

@Component
@Primary
public class MemoryMemberRepository implements MemberRepository{}

@Component
public class DemoMemberRepository implements MemberRepository{}
@Component
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberRepository memberRepository; // @Primary가 붙어있는 빈이 등록됨

}

4. 직접 애노테이션 만들어서 등록할 빈을 지정한다.

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier("mainRepo")
public @interface MainMemberRepository {
}
@Component
@MainMemberRepository
public class MemoryMemberRepository implements MemberRepository{}
@Component
public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository;
    
    @Autowired
    public MemberServiceImpl(@MainMemberRepository MemberRepository memberReposritory) {
        this.memberRepository = memberRepository;
    }
}

@Primary@Qualifier의 우선순위

스프링에서는 항상 자동보다 수동이, 넓은 범위 선택권보다 좁은 범위 선택권이 우선된다. 그래서 여기에서도 자동으로 빈 등록 우선권을 지정해주는 @Primary보다는 상세하게 어떤 빈을 등록할지 써주는 @Qualifier가 우선순위가 더 높다.

실무에서는 자주 사용하는 메인 빈을 @Primary로 지정해주고 가끔 사용하는 서브 빈이 필요한 곳에서만 @Qualifier를 써주는 방식으로 사용하면 된다.

자동 빈 등록 vs 수동 빈 등록 - 실무 운영 기준

기본적으로는 자동 빈 등록을 잘 활용하면 된다. 특히 스프링과 스프링 부트가 자동으로 등록하는 빈은 매뉴얼을 잘 보고 스프링이 의도한대로 잘 사용하도록 한다.

업무 로직에서 주로 사용되는 빈은 자동 기능을 적극적으로 사용한다. 보통 업무 로직은 비슷한 개발 패턴이 있고, 문제가 발생하는 곳도 비슷하기 때문에 나중에 문제가 생겨도 어디가 잘못 됐는지 금방 찾을 수 있다. 단, 다형성을 활용하는 업무 로직은 수동 빈 등록을 고민해보는 것도 필요하다.

데이터베이스 연결, 공통 로그 처리 같은 내가 직접 등록해서 사용하는 기술 지원 로직에는 수동 빈 등록으로 명시적으로 사용해야 나중에 잘못된 부분이 있을 때 찾기가 수월하다.

0개의 댓글