@AutoWired
등록된 빈을 주입하여 사용하고 싶을 때 사용하는 Annotation이다.
- 필요 한 의존 객체의 "타입"에 해당하는 빈을 찾아 주입한다.
- required의 기본값은 true이므로 빈을 찾지 못하면 App 구동 실패
- 생성자, 세터, 필드에서 사용할 수 있다. (생성자는 스프링 4.3부터 생략 가능)
1. 해당 타입의 빈이 한 개인 경우
- @Service와 @Repository를 통해 빈으로 등록하였으므로 정상적으로 빈을 찾아 주입한다.
@Repository를 제거했을 때
- Repository에 Annotation을 주지 않고 생성자를 통해 빈을 주입하려고 하면 에러가 발생한다.
생성자는 생성 시 userRepository의 Bean을 찾지 못해 에러가 뜨는 건 확실하나 Setter는 생성 시에는 아무런 영향을 미치지 않는데 에러가 나타난다.
- 그 이유는 @Autowired가 의존성 주입을 시도 하기 때문이다.
- 그러므로 @Autowired를 제거하면 아래와 같이 생성자는 그대로 에러가 뜨지만 Setter는 에러가 발생하지 않는다.
- 의존성이 옵션일 때는 @Autowired(required = false) 옵션을 주면 된다.
- required = false일 경우 의존성 주입을 시도하지만 빈으로 등록되지 않을 경우는 하지 않는다.
2. 해당 타입의 빈이 여러 개인 경우
- UserRepository를 인터페이스로 바꾸고 A, B Repository를 만든 후 UserRepository를 상속받는다.
방법 1
하나의 Repository에 @Primary를 하여야 한다.
방법 2
- AUserRepository를 사용하고 싶으면 이렇게 @Qualifier에 "AUserRepository"를 명시하면 된다.
방법 3
- 컬렉션을 통해 모든 Repository를 받아올 수도 있다.
- AppRunner를 통해 빈들을 확인하면 A, B Repository가 List에 들어가 있는 것을 알 수 있다.
방법 4
- Repository의 인스턴스를 만들 때 원하는 Repository로 만드는 방법
- 변수명을 빈으로 등록하기 원하는 클래스에 맞게 설정하면 된다.
- 이 방식이 가능한 것은 BeanPostProcessor Interface 때문이다.
- 아래의 lifecycle을 보면 12번 InitializingBean`s 전에 11번의 BeanPostProcessors에서 찾아준 후에 12번에서 빈이 Initializing 되기 때문이다.
- 이런 식으로 @PostConstruct를 사용하면 12번에서의 동작을 확인할 수 있다.
- 아래의 출력을 보면 빈이 정상적으로 등록되었고 앱 빌드 후가 아닌 중간에 출력이 되는 것을 알 수 있다.
'스프링 > 스프링 핵심 기술' 카테고리의 다른 글
6. IoC 컨테이너: MessageSource (0) | 2019.12.14 |
---|---|
5. IoC 컨테이너: Environment(Profile, Property) (0) | 2019.12.12 |
4. IoC 컨테이너: 빈의 스코프 (0) | 2019.12.12 |
3. IoC 컨테이너: @Component와 ComponentScan (0) | 2019.12.11 |
1. IoC 컨테이너: 스프링 IoC컨테이너와 빈 설정 방법들 (0) | 2019.12.10 |