스프링
스프링5 프로그래밍 입문 - 의존 자동 주입
담쏙
2023. 10. 2. 11:19
728x90
@Autowired
- @Autowired 애노테이션을 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입
- 자동 주입 대상이 필수가 아닌 경우에는
@Autowired(required=false)
로 지정- 빈이 존재하지 않을 때 자동 주입 대상이 되는 필드나 메서드에 null 을 전달하지 않음 (기본생성자에 있는 그대로 사용)
- 일치하는 빈이 없으면 값 할당 자체를 하지 않음
- 스프링5 부터는 의존 주입 대상에
Optional
을 사용해도 됨- 매칭되는 빈이 없으면 값이 없는
Optional
을 할당
- 매칭되는 빈이 없으면 값이 없는
@Autowired
public void setDateFormatter(Optional<DateTimeFormatter> formatterOpt) {
if (formatterOpt.isPresent()) {
this.dateTimeFormatter = formatterOpt.get();
} else {
this.dateTimeFormatter = null;
}
}
- @Nullalbe 애노테이션을 사용해도 된다
// 자동 주입할 빈이 존재하면 해당 빈을 전달하고, 아니면 null을 전달
@Autowired
public void setDateFormatter(@Nullable DateTimeFormatter datetimeFormatter) {
this.dateTimeFormatter = datetimeFormatter;
}
@Qualifier
- 자동 주입 가능한 빈이 두 개 이상일 때 자동 주입할 빈을 한정할 수 있음
@Bean
@Qualifier("printer")
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
@Bean
public MemberPrinter memberPrinter2() {
return new MemberPrinter();
}
@Autowired
@Qualifier("printer")
public void setPrinter(MemberPrinter printer) {
this.printer = printer;
}
- 필드와 메서드에 모두 적용할 수 있음
- 설정에 @Qualifier 애노테이션이 없으면 빈의 이름을 한정자로 지정
@Bean
public MemberPrinter printer() {
return new MemberPrinter();
}
@Bean
@Qualifier("mprinter")
public MemberPrinter printer2() {
return new MemberPrinter();
}
- printer() 메서드로 정의한 빈의 한정자는 빈의 이름인 “printer”가 됨
빈 이름 | @Qaulifier | 한정자 |
---|---|---|
printer | printer | |
printer2 | mprinter | mprinter |
infoPrinter | infoPrinter |
상위/하위 타입 관계와 자동 주입
@Bean
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
@Bean
public MemberPrinter memberPrinter2() {
return new MemberSummaryPrinter();
}
- bean 에러가 나는데, 이는 MemberSummaryPrinter가 MemberPrinter를 상속하고 있기 때문
- MemberSummaryPrinter 는 MemberPrinter 에도 할당할 수 있으므로 어떤 빈을 주입해야할 지 알 수 없어 Exception 발생
- @Qualifier를 사용하거나, Bean 리턴 타입 변경
자동 주입과 명시적 의존 주입 간의 관계
- 설정 클래스에서 세터 메서드를 통해 의존을 주입해도 해당 세터 메서드에 @Autowired 애노테이션이 붙어 있으면 자동 주입을 통해 일치하는 빈을 주입
- 의존 자동 주입과 수동 주입을 섞어 사용하고 있다면 일관되게 바꾸는 것이 나음