김영한님의 스프링 핵심 원리 - 기본편 강의
섹션7. 의존관계 자동 주입 강의 요약입니다.
결론
의존관계에는 주입에는 4가지 방법이 있지만 생성자 주입을 선택하자.
의존관계 주입 방법
- 생성자 주입
- 수정자 주입(setter 주입)
- 필드 주입
- 일반 메서드 주입
1. 생성자 주입 (Good Choice!)
- 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
- 불변, 필수 의존관계에 사용
- 생성자가 1개만 있으면,
@Autowired
생략해도 자동 주입된다. - 장점은 불변이다.
- 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없고,
- 대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안됨.(불변해야 한다.)
- 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없다. 불변!!!!
- final 키워드
- final을 사용할 수 있으므로, 컴파일 시점에 값이 설정이 되지 않았다면 오류 발생!
- 컴파일 오류는 가장 빠르게 원인파악 가능하고, Good 오류다.
- 어느 주입 방법도 final을 사용할 수 없음
@Component
public class OrderServiceImpl implements OrderService {
// final 불변 가능
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired //생략 가능
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
lombok 라이브러리가 제공하는 @RequiredArgsConstructor
를 사용하면 final이 붙은 필드를 모아서 생성자를 자동으로 만들어준다.
간결하게 생성자 주입이 가능해진다. 실제 out class를 열어보면 생성자 코드도 추가가 되어있다.
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
2. 수정자 주입(setter 주입)
- 선택, 변경 가능성이 있는 의존관계에 사용
- 수정자 메서드 사용하는 방식
- 단점
- setXXX메서드를 public으로 열어야 한다.
- 누군가가 실수로 변경할 수도 있는데, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아니다.
@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;
}
3. 필드 주입
- 코드가 간결해서 좋아보이지만, 외부에서 변경이 불가능해서 테스트하기 힘들다.
- DI 프레임워크가 없으면 아무것도 할 수 없다. -> 지양하자.
- 사용 용도
- 애플리케이션의 실제 코드와 관계 없는 테스트 코드
- 스프링 설정을 목적으로 하는 @Configuration 같은 곳에서만 특별한 용도로 사용
@Component
public class OrderServiceImpl implements OrderService {
@Autowired // Field injection is not recommended <- intellij도 경고하는 중
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
4. 일반 메서드 주입
- 한번에 여러 필드를 주입받을 수 있다.
- 잘 사용안함
@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;
}
정리
- 생성자 주입 방식을 선택하는 이유는 여러가지가 있지만, 프레임워크에 의존하지 않고, 순수한 자바 언어의 특징을 잘 살리는 방법이기도 하다.
- 기본으로 생성자 주입을 사용하고, 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다.
- 생성자 주입과 수정자 주입을 동시에 사용할 수 있다.
- 항상 생성자 주입을 선택하자. 그리고 가끔 옵션이 필요하면 수정자 주입을 선택해라. 필드 주입은 사용하지 말자
- 롬복을 적용하면
@RequiredArgsConstructor
이걸로 바로 가능! 편하다
'Study > 인프런' 카테고리의 다른 글
[강의 수강] 스프링 핵심 원리 - 기본편 (3) (0) | 2023.04.03 |
---|---|
[강의 수강] 스프링 핵심 원리 - 기본편 (2) (0) | 2023.03.19 |
스프링 컴포넌트 스캔과 의존관계 자동 주입 (0) | 2023.02.11 |
Spring @Configuration과 싱글톤 관계 (0) | 2023.02.05 |
스프링 개념 - 싱글톤 컨테이너란 (0) | 2023.02.05 |