1. 예제 프로젝트
- 의존 자동 주입
- 의존 대상을 설정코드에서 직접 주입하지 않고, 스프링이 자동으로 객체를 주입하는 기능
- 의존 주입 관련 애노테이션
- @Autowired
- @Resource : 자바에서 제공하는 애노테이션
2. @Autowired 애노테이션을 이용한 의존 자동 주입
- @Autowired
- 의존을 주입할 대상에 붙이는 애노테이션
- 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입
- 설정 파일에서 사용하기 위해 기본 생성자가 필요
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
- 세터 메서드의 자동 주입 구현 과정
- 기본 생성자를 추가
- 세터 메서드에 @Autowired 추가
- 설정 파일에서 기본 생성자로 return
- 일치하는 Bean이 없는 경우
- 타입이 일차히는 Bean이 없으면 Exception
- 타입이 일치하는 Bean이 2개 이상이면 Exception
3. @Qualifier 애노테이션을 이용한 의존 객체 선택
- @Qualifier
- 자동 주입 가능한 빈이 2개 이상일 때 지정하는 방법
// 설정 파일 내에서 등록된 빈
@Bean
@Qualifier("printer")
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
// 자동 주입하는 세터 메서드
@Autowired
@Qualifier("printer")
public void setMemberPrinter(MemberPrinter printer){
this.printer = printer;
}
- 빈 이름과 기본 한정자
빈 이름 | @Qualifier | 한정자 |
printer | printer | |
printer2 | mprinter | mprinter |
4. 상위/하위 타입 관계와 자동 주입
- 빈 등록과 상속 관련
- 시나리오
- MemberPrinter라는 객체가 빈으로 등록
- MemberPrinter가 자동 주입의 대상
- MemberPrinter를 상속받는 객체 MemberSummaryPrinter를 생성하여 빈으로 등록
- [에러] MemberSummaryPrinter가 MemberPrinter를 상속받아 MemberPrinter 타입으로 할당 가능
@Bean
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
@Bean
public MemberSummaryPrinter memberPrinter2() {
return new MemberSummaryPrinter();
}
- 해결방안
- 1) @Qualifier 애노테이션 활용
- 2) 자식 클래스 타입을 주입
- [의문] 자식 클래스 타입을 주입해도 여전히 MemberPrinter 타입 객체는 자동 주입이 불가능하지 않는가?
@Autowired
public void setMemberPrinter(MemberSummaryPrinter printer){
this.printer = printer;
}
5. @Autowired 애노테이션의 필수 여부
- @Autowired 애노테이션의 동작 관련
- 시나리오
- dataTimeFormatter가 null이어도 동작하도록 구현함
- @Bean으로 등록되지 않은 dataTimeFormatter에 @Autowired
- [결과] Exception 발생 : 등록된 빈이 없기 때문
- [문제] null이어도 동작하도록 구현하였는데 Exception이 발생함
- 해결방안
- 1) required 속성
주입 의존이 null이면 메서드가 호출되지 않음 - 2) 자바 8의 Optional
주입 의존이 null인지 isPresent() 메서드로 확인 가능 - 3) @Nullable
주입 의존이 null이면 null을 주입
- 1) required 속성
// 1) required 속성
@Autowired(require = false)
// 2) 자바 8의 Optional
@Autowired
public void setDataFormatter(Optional<DataTimeFormatter> formatterOpt) {
if (formatterOpt.isPresnet()){
this.dataTimeFormatter = formatterOpt.get();
} else {
this.dataTimeFormatter = null;
}
}
// 3) @Nullable
@Autowired
public void setDataFormatter(@Nullable DataTimeFormatter dataTimeFormatter) {
this.dataTimeFormatter = dataTimeFormatter;
}
- 생성자 초기화와 필수 여부 지정 방식 동작 이해
- 시나리오
- 생성자에서 dataTimeFormatter를 생성하여 저장 (초기화)
- 세터 메서드에 자동 주입 설정 (빈으로 등록되지 않음)
- 정상 동작
- 1) required 속성을 이용
dataTimeFormatter가 초기화한 객체로 사용됨 (메서드가 호출되지 않음) - 2) @Nullable을 이용
dataTimeFormatter가 null로 주입되어 null로 처리 (메서드가 호출됨)
- 1) required 속성을 이용
- [의문] 1) required 속성과 2) @Nullable의 차이를 유용하게 사용할 수 있는 상황은 어떤 상황이 있을까?
- 시나리오
6. 자동 주입과 명시적 의존 주입 간의 관계
- 자동 주입이 최종
- 설정 클래스에서 세터 메서드를 통해 의존을 주입하는 상황
- 해당 세터 메서드에 @Autowired 애노테이션이 붙어 있으면 자동 주입이 최종 실행
'책읽기' 카테고리의 다른 글
[스프링5 프로그래밍 입문][chap06] 빈 라이프사이클과 범위 (0) | 2022.03.10 |
---|---|
[스프링5 프로그래밍 입문][chap05] 컴포넌트 스캔 (0) | 2022.03.10 |
[스프링5 프로그래밍 입문][chap03] 스프링 DI (0) | 2022.03.04 |
[스프링5 프로그래밍 입문][chap01/chap02] 들어가며/스프링 시작하기 (0) | 2022.02.04 |
[파이썬 알고리즘 인터뷰] 14장 - 트리 (0) | 2021.09.13 |