본문 바로가기
반응형
Spring

[Spring] 스프링 핵심 원리 - 기본편 > 섹션 7. 의존관계 자동 주입

by brightGarden02 2024. 4. 11.

인프런 김영한 강사님의 [스프링 핵심 원리 - 기본편] 섹션7. 의존관계 자동 주입에 대한 요점 정리를 하였다.

 

목차

1.의존관계 주입방법

2.조회 빈이 2개 이상일 경우

3.어노테이션 직접 만들기

 


1.의존관계 주입방법

의존관계 주입 방법에는 크게 4가지가 있다.

1. 생성자 주입

2. 수정자 주입(setter 주입)

3. 필드 주입

4. 일반 메서드 주입

 

이 중에서 생성자 주입을 기본으로 사용하자. 대부분의 의존관계 주입은 변하면 안되기 때문이다.

수정자 주입 방식은 다른 필드 값들도 주입해주어야 하므로 누락의 가능성이 있다.

필드 주입은 테스트하기 어렵고 @Configuration 같은 특별한 용도에서만 사용한다. 

일반 메서드 주입은 한번에 여러 필드를 주입 받을 수 있지만 잘 사용하지 않는다.

 

 

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

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

생성자 주입은 생성자 호출 시점에 1번만 호출 되는 것이 보장되며

불변, 필수 의존관계에 사용한다.

또한 프레임워크에 의존하지 않고 순수한 자바 언어의 특징을 잘 살릴 수 있다.

생성자가 1개 있을 경우, @Autowired를 생략해도 자동 주입된다(스프링 빈에만 해당)

 


2.조회 빈이 2개 이상일 경우

조회 빈이 2개 이상이 될 경우, 어떤 빈을 사용할지 명시 해주지 않으면 오류가 난다. 이 경우는 @Qualifier, @Primary를 통해 해결 가능하다.

@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class OrderServiceImpl implements OrderService{

    private final MemberDao memberDao;
    private final OrderRepository orderRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberDao memberDao
                            , OrderRepository orderRepository
                            , @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
        this.memberDao = memberDao;
        this.orderRepository = orderRepository;
        this.discountPolicy = discountPolicy;
    }
}

 

@Qualifier는 상세한 설계를 할 경우 사용한다. @Qualifier("빈 이름")을 입력하며 설계한다. 생성자 주입시에는 파라미터 앞에  동일한 값을 입력하면 사용 가능하다. 

 

 

 

@Primary는 간략하게 해당 구체 클래스에 적용하여 사용 가능하다.

@Component
@Primary
public class FixDiscountPolicy implements DiscountPolicy {}

 

 

@Qualifier, @Primary가 적용되어 있을 경우, @Qualifier가 우선권을 갖는다. 스프링은 넓은 범위보다는 좁은 범위에서 선택권 우선순위가 높기 때문이다.

 


3.어노테이션 직접 만들기

@Quailfier("빈 이름")을 통해 의존관계를 명시해줄 수 있지만 컴파일시 타입 체크가 안된다. 이럴 경우, 어노테이션을 만들어서 해결 가능하다.

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


@Component
@MainDiscountPolicy
public class RateDiscountPolicy implements DiscountPolicy {}


@Component
public class FixDiscountPolicy implements DiscountPolicy {}


@Component
public class OrderServiceImpl implements OrderService{

    @Autowired
    public OrderServiceImpl(MemberDao memberDao
                            , OrderRepository orderRepository
                            , @MainDiscountPolicy DiscountPolicy discountPolicy) {
        this.memberDao = memberDao;
        this.orderRepository = orderRepository;
        this.discountPolicy = discountPolicy;
    }
 }

MainDiscountPolicy라는 어노테이션을 만들어서 해당 구체 클래스인 RateDiscountPolicy에 적용하고 OrderServiceImpl 생성자 주입시 해당 인터페이스 DiscountPolicy 앞에 어노테이션을 적용하여 해결하였다.

 

그러나 무분별하게 어노테이션을 재정의하면 이후 유지보수시 혼란을 가중할 수 있다. 주의하자.

 

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

 

스프링 핵심 원리 - 기본편 | 김영한 - 인프런

김영한 | 스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 백엔드 개발자가 되어보

www.inflearn.com

 

댓글


반응형
반응형