스프링 핵심 원리 - 기본편 # Section 7
2024. 7. 2. 23:43ㆍSpring/스프링 핵심 원리 - 기본편
반응형
❓ 다양한 의존관계 주입 방법
의존관계 주입 방법
- 생성자 주입
- 수정자 주입 (setter 주입)
- 필드 주입
- 일반 메서드 주입
생성자 주입
- 생성자를 통해서 의존 관계를 주입
- 특징
- 생성자 호출시점에 딱 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;
}
}
수정자 주입
- 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;
}
}
필드 주입
- 이름 그대로 필트에 바로 주입하는 방식
- 특징
- 코드가 간결하나, 외부에서 변경이 불가능해서 테스트 하기 힘듬
- DI 프레임워크가 없으면 아무것도 할 수 없다
- 사용하지 말것!
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
일반 메서드 주입
- 일반 메서드를 통해서 주입 받을 수 있다
- 특징
- 한번에 어려 필드를 주입 받을 수 있다
- 일반적으로 잘 사용하지 않음
@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;
}
}
❓ 옵션 처리
- 주입할 스프링 빈이 없어도 동작할 수 있게 처리
//호출 안됨
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
//null 호출
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
//Optional.empty 호출
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
❓ 조회 빈이 2개 이상
- @Autowired 는 타입으로 조회 함
- 같은 타입의 빈이 2개 이상 있을 때 오류 발생
- NoUniqueBeanDefinitionException 오류
위 문제를 해결 하기 위한 방법 3가지
@Autowrited 필드명
// 기존 코드
// - DiscountPolicy 타입이 스프링 빈에 2개가 등록 되어 있어 에러가 나는 상황
@Autowrired
private DiscountPolicy discountPolicy
// 오류 해결 방안
// - 필드명을 빈 이름으로 변경
@Autowrired
private DiscountPolicy rateDiscountPolicy
- 필드 명 매칭은 먼저 타입 매칭을 시도 하고 그 결과에 여러 빈이 있을 때 추가로 동작
@Qualifier
// 빈 등록 시 @Qualifier 를 붙여 준다.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
// 생성자 자동 주입 시
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
// 수정자 자동 주입 시
@Autowired
public DiscountPolicy setDiscountPolicy(@Qualifier("mainDiscountPolicy")
DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
- 빈 등록 시 @Qualifier 이름을 설정
- 자동 주입 시 @Qualifer("name") 으로 주입 가능
@Primary
// 같은 타입의 빈중 우선권 등록
// - 중복 타입 빈이 등록 됐을 때 @Primary 가 우선권을 가짐
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
//생성자
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
//수정자
@Autowired
public DiscountPolicy setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
강의 출처
반응형