@Autowired
- 이 어노테이션을 사용하면 스프링 컨테이너가 Bean으로 등록한 객체를 자동으로 주입해준다.
- 이때 일치하는 Bean이 꼭 존재해야 자동주입이 가능하고 없다면 기본적으로는 예외가 발생한다.
- 또한 같은 타입의 Bean이 두개일때도 예외가 발생한다.
**
@Qualifier
- 자동 주입 가능한 빈이 두개 이상이면 @Qualifier(“mprinter”) 처럼 직접 지정해줘야한다.
- 사용방법은 @Bean어노테이션으로 등록한 곳과 @Autowired으로 자동주입을 등록한 곳에서 사용 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @Autowired
@Qualifier("printer")
public void setPrinter(MemberPrinter printer) {
this.printer = printer;
}
@Bean
@Qualifier("printer")
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
@Bean
public MemberPrinter memberPrinter2() {
return new MemberPrinter();
}
|
@Qualifier 이 없으면 빈의 이름을 한정자로 지정한다.
- 아래 코드에서 printer() 메서드의 빈 이름 한정자는 printer이고
- printer2() 메서드의 빈 이름 한정자는 printer2가 아닌 “mprinter”이다.
1
2
3
4
5
6
7
8
9
10
| @Bean
public MemberPrinter printer(){
return new MemberPrinter();
}
@Bean
@Qualifier("mprinter")
public MemberPrinter printer2(){
return new MemberPrinter();
}
|
상속관계에서의 자동주입
- MemberSummaryPrinter는 MemberPrinter를 상속받은 클래스이다.
- 아래 코드는 정상적으로 실행될 것 같지만 에러가 난다. 스프링 컨테이너는 두 Bean 모두 MemberPrinter로 할당할 수 있기 때문이다.
- 해결방법은 @Qualifier 로 이름 한정자를 지정해주거나 @Autowired를 해주는 부분에서 명시적으로 MemberSummaryPrinter로 의존주입을 받게 해주면 된다.
1
2
3
4
5
6
7
8
9
| @Bean
public MemberPrinter printer(){
return new MemberPrinter();
}
@Bean
public MemberSummaryPrinter printer2(){
return new MemberSummaryPrinter();
}
|
@Autowired 어노테이션의 필수 여부
- 말 그대로 자동 주입이기 때문에 @Autowired 어노테이션을 사용하기 위해서는 스프링 컨테이너에 Bean으로 등록이 되어있어야 한다.
- 만약 @Autowired로 주입할 Bean이 등록되어있지 않다면 예외가 발생하게 된다.
- 다만 Bean으로 등록되어있지 않아도 예외가 나지 않도록 하는 방법이 3가지 존재한다.
1. @Autowired(required = false)
- 이때 Bean이 등록되어있지 않다면 스프링컨테이너는 자동주입 자체를 실행하지 않는다.
2. Optional
- Bean이 존재하지 않으면 값이 없는 Optional 전달해줌으로써 예외를 발생시키지 않는다.
1
2
3
4
5
6
7
8
9
| @Autowired
public void setDateFormatter(Optional<DateTimeFormatter> formatterOpt){
if(formatterOpt.isPresent()){
this.dateTimeFormatter = formatterOpt.get();
}
else{
this.dateTimeFormatter = null;
}
}
|
3. @Nullable
- @Nullable 어노테이션을 의존주입 파라미터 대상에 붙이면 Bean이 존재하지 않으면 null 을 전달한다.
- @Autowired(required = false)는 값 자체를 할당하지 않지만, @Nullable은 Bean이 없으면 null을 반드시 할당한다.
1
2
3
4
| @Autowired
public void setDateFormatter(@Nullable DateTimeFormatter dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
|
자동주입과 명시적 의존 주입간의 관계
- 예를 들어 @Autowired로 setter의존주입을 설정해놓은 상태에서 명시적으로 setter를 호출해서 주입을 하면 어떻게 될까?
- 이때 스프링 컨테이너는 @Autowired로 설정한 자동주입을 우선시한다.
- 그리고 @Autowired을 사용했다면 예외적인 상황을 제외하고 @Autowired를 사용해서 통일성을 유지하는 것이 좋다.
Leave a comment