스프링 핵심원리 기본편2
Intro
김영한님의 Spring 핵심원리 기본편을 듣고 정리한 내용을 공유합니다.
조회 대상 빈이 2개 이상일 때 해결 방법
1. @Autowired 필드 명 매칭
- DiscountPolicy의 구현체는 fixDiscountPolicy, rateDiscountPolicy가 있다고 가정
// 기존코드 @Autowired private DiscountPolicy discountPolicy
// 수정코드 @Autowired private DiscountPolicy rateDiscountPolicy
@Autowired는 타입 매칭을 시도하고, 이때 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다. 필드명이 rateDiscountPolicy이므로 정상적으로 주입된다.
2. @Qualifier는 @Qualifier끼리 매칭
- @Qualifier는 추가 구분자를 붙여주는 방법
- 주입 시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하는 것은 아니다.
// RateDiscountPolicy.class
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP) {
return price * discountPercent / 100;
} else {
return 0;
}
}
}
// FixDiscountPolicy.class
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {
private int discountFixAmount = 1000; // 1000원 할인
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP) {
return discountFixAmount;
} else {
return 0;
}
}
}
이제 위에 코드처럼 설정해두고 사용 할 때는 다음과 같이 설정 할 수 있다.
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
3. @Primary 사용
@Primary는 우선순위를 정하는 방법이며, @Autowired시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다.
@Component
public class FixDiscountPolicy implements DiscountPolicy {
private int discountFixAmount = 1000; // 1000원 할인
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP) {
return discountFixAmount;
} else {
return 0;
}
}
}
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP) {
return price * discountPercent / 100;
} else {
return 0;
}
}
}
이렇게 primary가 있으면 여러 빈이 선택되어도 다른것을 다 무시하고 RateDiscountPolicy를 우선순위를 최상으로 하여 의존관계 주입한다.
4. @Primary, @Qualifier 활용
코드에서 자주 사용하는 메인 데이터베이스의 커넥션을 획득하는 스프링 빈이 있고, 코드에서 특별한 기능으로 가끔 사용하는 서브 데이터베이스의 커넥션을 획득하는 스프링 빈이 있다고 했을 경우
- 메인 데이터베이스의 커넥션 획득
- @Primary를 적용하여 조회하는 곳에서 @Qualifier 지정 없이 편리하게 조회
- 서브 데이터베이스 커넥션 획득
- @Qualifier를 지정하여 명시적으로 획득하는 방식
- @Primary와 @Qualifier의 우선순위
- @Primary(넓은 범위)는 기본 값처럼 동작하고, @Qualifier(좁은 범위)는 상세하게 동작하기에 좁은 범위의 선택권을 가진 @Qualifier의 우선 순위가 높다.
5. 빈 생성주기 콜백
- 스프링 빈의 이벤트 라이프사이클
- 스프링 컨테이너 -> 생성 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용-> 소멸전 콜백 -> 스프링 -> 종료
- 객체의 생성과 초기화를 분리
- 생성자는 객체 생성에 책임을 가진다.
- 초기화는 생성된 값들을 활용하여 커넥션 연결과 같은 무거운 동작을 수행한다.
- 스프링의 빈 생명주기 콜백 지원 방법
- 인터페이스(initializingBean, DisposableBean) -> 거의 사용하지 않음
- 설정 정보에 초기화 메서드나 종료 메서드 지정 -> @Bean(initMethod = “init”, destroyMethod = “close”)
- @PostConstruct, @PreDestory 에너테이션 지원
Leave a comment