@Autowired
필요한 의존 객체의 “타입”에 해당하는 빈을 찾아 주입한다.
생성자, 세터, 필드에 사용가능하다 아래 예시를 참고하자.
BookService의 생성자에 Autowired를 달았다. 잘동작할것이다.
1 | @Service |
이번에는 세터에다 Autowired를 달아주고 @Repository를 지워보자.
1 | @Service |
위는 실패하는데 왜 실패할까단순 세터에 Autowired만 붙였으므로 인스턴스 생성은 되어야 하는거아녀?
Autowired가 있기때문에 의존성 주입을 시도하게되고 이로 인해 실패한다.
실패를 벗어나기 위해서는 @Autowired(require = false)로 해결할 수 있다.
즉 생성자가 아닌곳에 붙은 @Autowird는 require = false 옵션을 적절히 활용할 수 있다.
(생성자에 Autowired(required = false) 가 붙어있으면 객체 자체 생성이 불가능하므로 생성자에는 부적절)
해당 타입의 빈이 여러개인 경우
1 | interface A { |
AService의 aRepository에는 누가 주입될까?
내가 어떤걸 원하는지 스프링은 모르기 때문에 에러가 발생한다.
해결방법은?
@Primary 어노테이션 붙이기 (추천)
1
2
3
4@Repository @Primary
class CRepository implements ARepository {
..
}위처럼 할경우 CRepository가 주입된다.
Qualifier 활용
1
2
3
4
5@service
public class AService {
@Autowired @Qualifier("cRepository")
ARepository aRepository;
}위처럼 할경우 CRepository가 주입된다.
해당 타입의 빈 모두 주입받기
1
2
3
4
5@service
public class AService {
@Autowired
List<ARepository> aRepository;
}리스트에 BRepository , CRepository가 들어간다.
추천하진 않지만 알고만 있어라
1
2
3
4
5@service
public class AService {
@Autowired
ARepository cRepository;
}
Autowired는 타입만 보는것이 아니라 이름도 한번 보기때문에 위처럼 할 경우 cRepository를 주입받을 수 있다.
동작원리는?
BeanPostProcessor
새로 만든 빈 인스턴스를 수정할 수 있도록 도와주는 인터페이스이다.
AutowiredAnnotationBeanPostProcessor extends BeanPostProcessor
위에 보다시피 AutowiredAnnotationBeanPostProcessor가 BeanPostProcessor을 상속하여 사용하는데 초기화 이전에 @Autowired같은 어노테이션을 찾아 주입을 해준다.
이제 동작원리 설명
ApplicationContext (BeanFactory)가 BeanPostProcessor을 구현한 빈을 찾고 AutowiredAnnotationBeanPostProcessor를 찾아 일반적인 빈들에게 해당 로직을 적용하는것이다.
(결국 AutowiredAnnotationBeanPostProcessor도 빈으로 등록되어있다는것)
(ApplicationContext는 빈 들을 갖고있다)