티스토리 뷰
Spring의 @Autowired와 그 쓰임새를 알아보자.
@Autowired를 이용하면 필요한 의존 객체에 해당하는 빈을 찾아 필드 또는 파라미터명에 주입할 수 있다.
@Autowired는 Spring 컨테이너가 관리하는 Bean에서만 사용이 가능하다.
@Autowired 로 Bean을 매칭하는 방법
타입 매칭 (같은 타입이거나 그 타입의 자식들을 다 가져옴)
타입 매칭의 결과가 2개 이상인 경우 필드명 또는 파라미터명 으로 빈 이름 매칭하여 주입
- 해당하는 이름의 빈이 없으면 NoUniqueBeanDefinitionException 오류가 발생한다.
2.와 같이 매칭 결과가 여러개인 경우, 특정 빈을 주입받기 위한 방법 ?
예시) DiscountPolicy를 상속받는 FixDiscountPolicy, RateDiscountPolicy가 있는데,
DiscountPolicy를 주입받는 경우@Component public class OrderServiceImpl implements OrderService { // c.f) 왜 FixDiscountPolicy나 RateDiscountPolicy로 주입받지 않음 ? -> DIP준수 (SOLID와 다형성) private final DiscountPolicy discountPolicy; private final MemberRepository memberRepository; @Autowired public OrderServiceImpl(DiscountPolicy discountPolicy, MemberRepository memberRepository){ this.discountPolicy = discountPolicy; this.memberRepository = memberRepository; } // ... }
위와 같은 경우 discountPolicy에 FixDiscountPolicy를 주입하려면 어떻게 해야할까?
@Qualifier("name")를 이용
- 빈(클래스)에 @Qualifier("name")를 붙이고
- 해당 빈을 주입받을 필드 또는 파라미터에 @Qualifier("name")를 붙여주면 됨
@Primary
- 위와 같은 예시의 경우 FixDiscountPolicy 빈에 @Primary를 붙여주면
- 위 코드와 같은 경우 DiscountPolicy에 FixDiscountPolicy빈이 주입이 됨
@Primary와 @Qualifier("name")를 모두 활용하여 깔끔하게 빈을 관리할 수 있다.
- 메인 데이터베이스의 커넥션을 획득하는 스프링빈과 특별한 기능으로 가끔 사용하는 데이터베이스의 커넥션을 획득하는 스프링빈이 있음
- 메인 데이터베이스의 스프링빈은 @Primary를 사용
- 서브 데이터베이스의 스프링빈은 @Qualifier("name")를 사용
@Primary와 @Qualifier의 우선순위는 @Qualifier가 더 높다.
- @Autowired를 이용한 의존관계 주입방법
- 생성자 주입
- 불변, 필수적인 의존관계에 있을때 효과적
- 생성자가 하나인 경우 @Autowired생략가능
- 수정자(Setter) 주입
- 선택, 변경 가능성이 있는 의존관계에 사용
- 필드 주입
- DI 컨테이너에 의존적인 방법
- 실제 어플리케이션 코드에는 적용하지 않는것이 좋음
- Test코드 작성시에는 유용함
- 생성자 주입
롬복을 이용한 자동 의존관계 주입
막상 개발해 보면 대부분 불변의 의존관계를 가짐
불변의 관계의 경우 final을 사용함
위와 같은 상황에서 생성자 주입방법과 Lombok의 @RequiredArgsConstructor를 이용하면 코드를 깔끔하게 줄일 수 있음 ("@Autowired 로 Bean을 매칭하는 방법"에서의 예시코드와 비교)
@Component @RequiredArgsConstructor public class OrderServiceImpl implements OrderService { private final DiscountPolicy discountPolicy; private final MemberRepository memberRepository; // 아래의 코드를 생략할 수 있음 //@Autowired //public OrderServiceImpl(DiscountPolicy discountPolicy, MemberRepository memberRepository){ // this.discountPolicy = discountPolicy; // this.memberRepository = memberRepository; //} // ... }
'개발 공부 > Spring' 카테고리의 다른 글
Spring Boot Devtools 사용법 (4) | 2021.10.30 |
---|