다양한 의존관계 주입 방법
크게 4가지가 있다.
- 생성자 주입
- 수정자 주입(setter주입)
- 필드 주입
- 일반 메소드 주입
생성자 주입
이 방법은 객체를 생성할 때 생성자를 통해 의존성을 주입하는 방식이다. 스프링이 클래스의 생성자를 분석하여 필요한 의존 객체를 자동으로 주입한다.
- 생성자 호출시점에 1번만 호출되는 것이 보장된다.
- 주로 불변, 필수 의존관계에 주로 사용한다. 왜냐하면 생성자는 딱 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를 생략해도 자동 주입된다. 생성자 주입과 수정자 주입을 동시에 사용할 수 있다.
수정자 주입(setter 주입)
Setter 메서드를 통해 의존성을 주입하는 방식이다. 주로 선택 ,변경 가능성이 있는 의존 관계에 사용에 사용한다
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DisCountPolicy disCountPolicy;
@Autowired(required = false)
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDisCountPolicy(DisCountPolicy disCountPolicy) {
this.disCountPolicy = disCountPolicy;
}
}
※ Autowired만 사용하면 required 옵션의 기본 값이 true로 되어 있어서 자동 주입이 안되면 오류가 발생한다.
required=false 자동 주입할 대상이 없으면 그냥 넘어가어 간다
필드 주입
주로 권장하지 않는 방법이다. 프레임워크가 없으면 테스트를 할 수가 없다.
단 사용하는 경우가 2가지 있다.
- 테스트 자바 파일에서
- 설정하는 Configuration이 있는 자바 파일에서 사용
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
메소드 주입
메소드 주입은 한 번에 여러 필드를 주입받을 수 있는 장점이 있지만, 일반적으로는 사용되지 않는다. 이유는 메소드 주입이 객체의 생성 시점에 의존성을 명확하게 나타내지 않기 때문이다. 일반적으로 생성자 주입이나 Setter 주입을 사용할 때, 객체가 생성될 때 모든 의존성이 명시적으로 주입되어 생성 시점에 객체의 완전성을 보장할 수 있다.
@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;
}
}
그리고 메소드 주입은 일반적으로 객체가 생성되고 초기화 메소드를 이용하여 의존성을 주입 받기 때문에 유지보수나 다른 사람이 코드를 볼때 불편함을 야기할 수 있다
이러한 이유 때문에 생성자 주입을 사용하는 것이 좋다
생성자 주입을 선택해야 되는 이유
스프링을 포함한 DI 프레임워크 대부분이 생성자 주입을 권장한다.
그 이유는 다음과 같다.
불변
- 대부분의 의존관계 주입은 한번 일어나면 애플케이션 종료시점까지 의존관계를 변경할 일이 없다. 오히려 대부분의 의존 관계는 애플리케이션 종료 전까지 변경하면 안된다.
- 수정자 주입을 사용하면, setXxx 메소드를 public으로 만들어야 한다. 이때 다른 사람이 실수로 변경할 수 있고, 변경하면 안되는 메소드를 만드는 것은 좋은 설계 방법이 아니다.
- 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없다. 따라서 불변으로 설계할 수 있다.
프레임워크 없이 순수 Java 코드를 단위 테스트하는 경우
프레임워크 없이 순수 Java 코드를 단위 테스트하는 경우 수정자 주입으로 인해 NullPointerException이 발생할 수 있는 반면에 생성자 주입은 컴파일 오류가 발생하기 때문에 디버그 처리가 훨씬 편리하다
'Spring' 카테고리의 다른 글
[Spring] 스프링이 제공하는 ExceptionResolver에 대하여 (0) | 2024.07.08 |
---|---|
[Spring] 스프링이 제공하는 HandlerExceptionResolver에 대해서(ExceptionHandlerExceptionResolver) (0) | 2024.07.04 |
[OAuth2.0 + JWT + Spring] 스프링 시큐리티로 OAuth2.0 로그인 구현(카카오) (0) | 2024.07.01 |
[Spring] Spring 기본 개념 - 스프링 컨테이너 (1) | 2024.03.24 |
[spring] 스프링 빈의 기본 개념 (0) | 2024.03.24 |