해당 게시물은 백기선님의 스프링 프레임워크 핵심 기술 강좌를 정리한 내용 입니다.
1. @Autowired
- @Autowired는 필요한 의존 객체의 “타입"에 해당하는 빈을 찾아 주입한다.
2. @Autowired의 required
- @Autowired의 required는 true가 기본 값이다.
필요한 의존 객체의 타입에 해당하는 빈을 찾지 못하면 애플리케이션 구동에 실패한다.
@Service
public class BookService {
BookRepository bookRepository;
@Autowired
public void setBookRepository(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
- BookRepository가 빈으로 등록되어 있지 않다고 가정 할 때,
아래 코드에서 required를 false로 지정 하면, 의존성 주입을 할 수 없더라도 애플리케이션을 구동한다.
즉, BookRepository가 의존성 주입이 되지 않은 상태로 BookService가 빈으로 등록된다.
@Service
public class BookService {
BookRepository bookRepository;
@Autowired(required = false)
public void setBookRepository(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
- 해당 내용은 필드에도 적용 가능 하다.
@Service
public class BookService {
@Autowired(required = false)
BookRepository bookRepository;
}
3. @Autowired를 사용 할 수 있는 위치
- @Autowired는 생성자, 세터(setter), 필드(field)에 사용 할 수 있다.
① 생성자
@Service
public class BookService {
BookRepository bookRepository;
@Autowired
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
② 세터(setter)
@Service
public class BookService {
BookRepository bookRepository;
@Autowired
public void setBookRepository(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
③ 필드(field)
@Service
public class BookService {
@Autowired
BookRepository bookRepository;
}
4. 같은 타입의 빈이 여러 개 일 때, 의존성 주입
아래의 BookRepository 인터페이스를 구현한 클래스(MyBookRepository, KeesunBookRepository)가 2개 있다.
public interface BookRepository { }
@Repository
public class MyBookRepository implements BookRepository { }
@Repository
public class KeesunBookRepository implements BookRepository{ }
BookService 클래스에서는 @Autowired로 BookRepository를 주입 받으려고 하는데 에러가 발생한다.
에러가 발생한 이유는 두 개의 클래스 중 어떤 클래스를 주입해야 하는지 알 수 없기 때문이다.
@Service
public class BookService {
@Autowired
BookRepository bookRepository;
}
해결책으로는 다음 3가지가 존재한다.
① @Primary : 같은 타입의 빈이 여러 개 일 때, 우선 순위를 가지는 빈으로 지정하여 해당 빈이 주입 되도록 한다.
@Repository
@Primary
public class KeesunBookRepository implements BookRepository{}
② @Qualifier : @Autowired와 함께 사용하며 빈의 이름이 같은 객체를 찾는다.
* 빈의 이름 : @Service 또는 @Repository 등이 붙은 클래스 명에서 첫 글자만 소문자로 변경한 것이다.
@Qualifier 보다 좀 더 type-safe 한 @Primary를 사용하는 것을 권장한다.
@Autowired
@Qualifier("keesunBookRepository")
BookRepository bookRepository;
③ 해당 타입의 모든 빈을 주입 받기
다음과 같이 List를 사용하면 해당 타입의 (BookRepository) 타입의 모든 빈을 주입 받을 수 있다.
@Autowired
List<BookRepository> bookRepository;
어떠한 빈이 주입 되었는지 확인 하기 위해 다음과 같이 Runner를 만든다.
(Runner에 대한 자세한 내용은 스프링 부트 강좌를 참고)
@Component
public class BookServiceRunner implements ApplicationRunner {
@Autowired
BookService bookService;
@Override
public void run(ApplicationArguments args) throws Exception {
bookService.printBookRepository();
}
}
BookService에 어떤 BookRepository 빈이 주입 되었는지 출력하는 메서드를 정의한 다음, BookServiceRunner에서
해당 메서드를 호출한다.
@Service
public class BookService {
@Autowired
BookRepository bookRepository;
// BookService에 어떤 BookRepositor빈이 주입 되었는지 출력하는 메서드 정의
public void printBookRepository(){
System.out.println(bookRepository.getClass());
}
}
5. @Autowired 동작 원리
BeanPostProcessor의 구현체인 AutowiredAnnotationBeanPostProcessor가 Bean의 초기화 라이프 사이클 이전에
@Autowired 애노테이션이 붙어 있는 빈(Bean)을 찾아 주입 한다.
'Spring > Spring Core' 카테고리의 다른 글
| [Section 1] IoC 컨테이너 5부: 빈의 스코프(Scope) (0) | 2020.09.03 |
|---|---|
| [Section 1] IoC 컨테이너 4부: @Component와 컴포넌트 스캔 (0) | 2020.09.03 |
| [Section 1] IoC 컨테이너 2부: ApplicationContext와 다양한 빈 설정 방법 (0) | 2020.09.02 |
| [Section 1] IoC 컨테이너 1부: 스프링 IoC 컨테이너와 빈 (0) | 2020.09.01 |
| [Section 0] 스프링 소개 (0) | 2020.09.01 |
댓글