이전 편에서는 컴포넌트 스캔을 통해 빈을 자동 등록하고, 생성자에 @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;
}
}
- 생성자 주입은 불변성(immutable) 을 보장할 수 있다.
- final 키워드와 함께 사용하면, 필수 의존관계임을 명확히 할 수 있다.
- 생성자가 하나뿐이면 @Autowired 생략 가능
왜 추천될까?
- 생성 시점에 모든 의존성이 주입되므로, 객체가 완전히 초기화된 상태로 사용 가능
- 테스트 코드에서 명확한 주입이 가능
2. 수정자(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;
}
}
- 스프링 컨테이너가 객체 생성 후, setter를 통해 의존성 주입
- 선택적으로 의존관계를 주입할 때 유용
- @Autowired(required = false)로 선택적 주입 가능
단점
- 객체가 완전히 초기화되지 않은 상태로 사용될 수 있음
- 불변성을 깨뜨림 → 유지보수 어려워짐
3. 필드 주입
절대 쓰지 말자
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
- 간결하고 편리하지만 테스트가 매우 어려움
- 의존성을 변경할 수 없기 때문에 불변성 보장도 안 됨
- 외부에서 주입할 수 없어 DI 프레임워크에 강하게 결합
필드 주입은 테스트 코드도 작성하기 어렵고, 실제 코드가 스프링에 너무 의존적이기 때문에 안티패턴으로 간주됨. 절대 사용 금지
4. 일반 메서드 주입
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
- 한 번에 여러 의존성을 주입받고 싶을 때 사용
- setter 주입과 거의 유사하지만 일반 메서드에서 사용 가능
- 잘 사용되진 않음
5. 자동 주입이 되기 위한 조건
- @Autowired는 스프링 컨테이너가 관리하는 빈만 주입 가능
- new 키워드로 생성한 객체에는 아무 동작도 하지 않음
- 스프링 빈 외부 객체에는 작동하지 않음
설계 원칙 정리
방식 | 특징 | 사용 시점 |
생성자 주입 | 불변 + 필수 | 대부분의 경우, 가장 권장 |
수정자 주입 | 선택적 + 변경 가능 | 조건부 의존성일 때 |
필드 주입 | 외부 주입 불가 | 테스트 불가, 사용 금지 |
일반 메서드 주입 | 한 번에 여러 의존성 주입 | 거의 사용하지 않음 |
'Spring' 카테고리의 다른 글
[Spring 완전 정복 시리즈] 19편 - 자동 주입 고급 기능과 전략 패턴 적용법 (3) | 2025.07.30 |
---|---|
[Spring 완전 정복 시리즈] 18편 - 의존관계 자동 주입 방식 완전 정리 (0) | 2025.07.30 |
[Spring 완전 정복 시리즈] 16편 - 컴포넌트 스캔 심화 (0) | 2025.07.29 |
[Spring 완전 정복 시리즈] 15편 - 컴포넌트 스캔의 시작 (0) | 2025.07.29 |
[Spring 완전 정복 시리즈] 14편 - @Configuration과 바이트코드 조작의 마법 (1) | 2025.07.28 |