의존성 주입 애노테이션(@Autowired,@Resource,@Inject)

@Autowired

  • 스프링 프레임워크에서 제공하는 애노테이션이다.
  • @Autowired는 타입 매칭을 시도 하고 , 여러 빈이 있으면 필드 이름(파라미터 이름)으로 빈 이름을 추가 매칭한다.
  • ac.getBean(클래스.class) 이 코드와 유사하게 동작한다. (실제로는 더 많은 기능을 제공한다)
  • 필드 , 생성자 , Setter에 붙일 수 있다.
    • 단, 필드 또는 Setter에 붙여서 사용할 경우 반드시 기본 생성자가 정의 되어 있어야 한다.

@Resource

  • 자바에서 제공하는 애노테이션이다.
  • @Resource는 주입하려고 하는 객체의 이름(인스턴스 명)이 일치하는 객체를 자동으로 주입한다.
  • 필드 , Setter에 붙일 수 있다.
    • 반드시 기본 생성자가 정의 되어 있어야 한다.

@Inject

  • @Inject는 @Autowired와 유사하게 주입하려고 하는 객체의 타입과 일치하는 객체를 자동으로 주입한다.
  • 자바에서 제공하는 애노테이션이다.
  • 필드 , 생성자 ,  Seeter에 붙일 수 있다.
    • 단, 필드 또는 Setter에 붙여서 사용할 경우 반드시 기본 생성자가 정의 되어 있어야 한다.
  • @Named 사용
    • @Autowired의 @Qualifier와 같이 사용할 수 있는 것이 @Inject에서는 @Named이다.

조회 대상 빈이 2개 이상일 때 해결 방법

@Autowired 필드 명 매칭

// 생성자 주입
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
	this.memberRepository = memberRepository;
	this.discountPolicy = discountPolicy;
}
  • DiscountPolicy - 인터페이스
  • FixDiscountPolicy , RateDiscountPolicy - 구현체
  • 현재 구현체 2개 다 @Component 애노테이션으로 인해 스프링 빈으로 등록 되어 있는 상태다.
  • 이대로 테스트를 실행하면 NoUniqueBeanDefinitionException 예외가 발생한다.
    • (DiscountPolicy의 하위 타입으로 참조할 수 있지만 DIP를 위배하고 유연성이 떨어진다.)
// 생성자 주입
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
	this.memberRepository = memberRepository;
	this.discountPolicy = rateDiscountPolicy;
}
  • 필드 명을 빈 이름으로 변경한 후 테스트를 실행하면 성공적이다.
  • 필드 명 매칭은 먼저 타입 매칭을 시도 하고 , 그 결과에 여러 빈이 있을 때 추가로 동작하는 기능이다.

 

@Qualifier 사용

@Qualifier  → @Qualifier 끼리 매칭 → 빈 이름 매칭

  • 수정자(Setter) , 생성자 , 필드 주입에서 사용 가능하다
@Component
@Qualifier("mainPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
	...
}
@Component
@Qualifier("subPolicy")
public class FixDiscountPolicy implements DiscountPolicy{
	...
}
//생성자 주입
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, 
                        @Qualifier("mainPolicy") DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}
  • @Qualifier로 주입할 때 mainPolicy를 못찾으면 mainPolicy라는 이름의 스프링 빈을 추가로 찾는다.
  • 하지만 @Qualifier는 @Qualifier를 찾는 용도로만 사용하는게 명확하고 좋다.

 

@ Primary 사용

우선순위를 정하는 방법이다. @Autowired시에 빈이 여러개 매칭 되면 @Primary가 우선권을 가진다.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{
	...
}
@Component
public class FixDiscountPolicy implements DiscountPolicy{
	...
}
  • @Primary가 중복 되면 NoUniqueBeanDefinitionException 예외가 발생한다.

 

 

우선순위

@Primary는 기본값 처럼 동작하는 것이고 , @Qualifer는 매우 상세하게 동작한다.

스프링은 자동보다는 수동이 , 넓은 범위의 선택권 보다는 좁은 범위의 선택권이 우선 순위가 높다.

따라서 여기서도 @Qualifier가 우선권이 높다.

 

 

 

스프링 빈 조회

빈 출력 해보기 ApplicationContextInfoTest public class applicationContextInfoTest { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); @Test @DisplayNam..

write-read.tistory.com

 

[Spring] 의존성 주입 애노테이션 정리 - @Autowired, @Resource, @Inject

[Spring] 의존성 주입 애노테이션 정리 - @Autowired, @Resource, @Inject 1. @Autowired @Autowired는 주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입한다. @Autowired는 필드, 생성자, Setter에..

atoz-develop.tistory.com

 

스프링 핵심 원리 - 기본편 - 인프런

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 초급 프레임워크 및 라이브러리 웹 개발 서버 개발 Back-End Spring 객체지향 온

www.inflearn.com

 

'기록 > Spring' 카테고리의 다른 글

Annotation 직접 만들기  (0) 2021.01.02
Lombok 사용해보기  (0) 2020.12.30