티스토리 뷰

의존성 주입

DI는 디자인 패턴으로 크게 다음과 같이 4가지 방법이 있다.

  • 생성자 주입
  • setter 주입
  • 필드 주입(@Autowired)
  • 일반 메서드 주입

생성자 주입

  • 이름 그대로 생성자를 통해서 의존 관계를 주입 받는 방법
  • 생성자 호출 시점에 단 1번만 호출되는 것이 보장된다.
  • 불변, 필수 의존 관계에 사용
@Component
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

}

생성자가 1개만 있으면 @Autowired를 생략해도 자동 주입 된다. (스프링 빈에만 해당)

@Component
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    // 생성자가 1개일 경우, @Autowired 생략 가능
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

}

setter 주입

  • 필드의 값을 변경하는 수정자 메서드(setter)를 통해서 의존관계를 주입하는 방법
  • 선택, 변경 가능성이 있는 의존 관계에 사용
@Component
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

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

    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }

}
  • @Autowired의 기본 동작은 주입할 대상이 없으면 오류가 발생하므로, 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false)로 지정해야 한다.

필드 주입(@Autowired)

  • 이름 그대로 필드에 바로 주입하는 방법
  • 외부에서 변경이 불가능해서 테스트 하기 힘들다.
  • DI 프레임워크가 없으면 아무것도 할 수 없다.
  • 아래 두 경우를 제외하곤, 사용하지 말자
    • 테스트 코드
    • 스프링 설정을 목적으로 하는 @Configuration 같은 곳에서만 특별한 용도로 사용
@Component
public class OrderServiceImpl implements OrderService {

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private DiscountPolicy discountPolicy;
}
  • 순수한 자바 테스트 코드에는 @Autowired가 동작하지않고, @SpringBootTest처럼 스프링 컨테이너를 테스트에 통합한 경우에만 가능

일반 메서드 주입

  • 일반 메서드를 통해서 주입 받는 방법
  • 한번에 여러 필드를 주입 받을 수 있다.
  • 일반적으로 잘 사용하지 않는다.
@Component
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함