일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Disjoint-set
- spring
- 최소신장트리
- MST
- ==
- web
- 구현
- Graph
- Integer
- bruteforce
- Floyd-Warshall
- DFS
- back-end
- 그래프
- Web-BackEnd
- BFS
- spring-boot
- 완전탐색
- Prim
- HashMap
- SSAFY
- Spring Framework
- ssafy서울
- java
- Union-FInd
- Kruskal
- 삼성청년SW아카데미
- cycle
- 시뮬레이션
- equals
- Today
- Total
devlog
IoC 컨테이너 : @Autowired 본문
@Autowired
필요한 의존 객체의 Type에 해당하는 빈을 찾아 주입한다.
1. @Autowired
- required : 기본값은 true 따라서 의존 객체가 빈으로 등록되지 않으면 애플리케이션 구동이 실패한다. 하지만 false로 둘 경우 의존성 없이도 실행가능 (빈으로 등록이 가능)
사용가능한 위치
- 생성자
- 생성자를 통해 주입을 받는 경우는 빈을 생성할 때에도 (인스턴스를 생성할 때에도) 개입이 되기 때문에 파라미터로 넘겨진 타입의 빈이 (의존 객체가) 없으면 인스턴스를 만들지 못한다. 다른 두 방법에 비해 명시적이고 오류를 발견하기 쉽다.
- 즉, 의존관계를 주입하지 않은 경우 인스턴스를 생성할 수 없기 때문에 의존 관계에 대한 내용이 외부로 노출되어 컴파일타임에 에러를 발견할 수 있다.
- final 키워드를 사용할 수 있다 : 빈으로 등록할 객체 내부에서 의존관계에 있는 객체를 바꿔치기 할 수 없다.
- 스프링 4.3 부터는 생성자가 하나일 경우 생략이 가능하다.
@Service public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } }
- Setter
- Field
Setter 방식과 Field 방식은 일반적으로는 의존 객체가 빈으로 등록되있지 않으면 에러를 발생시키지만, 의도적으로 @Autowired(required = false) 옵션을 준다거나 인위적으로 의존관계의 객체가 생성이 되지 않은 상태에서도 동작하게 할 경우 해당 빈의 인스턴스는 생성되므로 NullPointerException의 에러를 발생시킬 수 있다.
즉, 의존성 주입이 필요한 객체가 주입되지 않아도 얼마든지 인스턴스를 생성할 수 있다는 것이 문제이다.
@Service public class UserService { private final UserRepository userRepository; @Autowired(required = false) public void setUserService(UserRepository userRepository) { this.userRepository = userRepository; } }
생성자를 통한 주입의 장점
- 의존관계가 설정되지 않으면 객체를 생성할 수 없다 : 컴파일 타임에 에러발견 가능 + NullPointerException 방지
- 의존 객체를 final로 선언할 수 있다 : Immutable
- 순환참조 감지 : 컨테이너가 빈을 생성하는 시점에 순환참조가 발생하면 앱 구동이 실패
- 테스트코드 작성이 용이하다
2. 컨테이너에서 주입하려는 빈이 여러개 존재할 경우
- 해당 타입의 빈이 없는 경우 : 인스턴스 생성 불가능
- 해당 타입의 빈이 한 개인 경우 : 인스턴스 생성 가능
- 해당 타입의 빈이 여러개인 경우
- 빈 이름으로 시도
- 같은 이름의 빈을 찾으면 해당 빈을 사용 : 인스턴스 생성 가능
- 같은 이름의 빈을 찾지 못하면 실패 : 인스턴스 생성 불가능
일반적으로 해당 타입의 빈이 여러개인 경우 스프링은 사용자가 원하는 것이 무었인지 모르기 때문에 의존성 주입이 불가능하다. 이를 해결하기 위한 방법으로 3가지가 있다.
- @Primary : 주로 사용하고 싶은 빈이 무었인지 마킹한다. @Qualifier 방식보다 추천
- 해당 타입의 빈을 모두 주입받는다.
- @Qualifier : 사용하고 싶은 빈을 마킹한다. @Qualifier("name")
@Service public class BookService { @Autowired List<BookRepository> bookRepositories; }
모든 빈을 주입받는 경우 위의 코드와 같이 List 를 사용해서 넘겨받을 수 있다.
3. @Autowired 의 동작 원리
- BeanPostProcessor : 빈의 인스턴스를 만든다음 빈의 초기화 라이프사이클 이전 또는 이후(@PostConstruct)에 또 다른 작업을 할 수있는 라이프 사이클 콜백
- AutowiredAnnotationBeanPostProcessor : 하나의 빈으로써 스프링 컨테이너에 등록되어 있다. 빈의 초기화 라이프 사이클 이전에 @Autowired를 처리한다.
'Spring > 이론' 카테고리의 다른 글
IoC 컨테이너 : 스프링 IoC 컨테이너와 빈 (0) | 2020.08.11 |
---|---|
🌱Spring Framework : MyBatis (0) | 2020.05.26 |
🌱Spring Framework : Spring Web MVC (0) | 2020.05.19 |
🌱Spring Framework : Aspect-Oriented Programming (0) | 2020.05.19 |
🌱Spring Framework : Dependency Injection (0) | 2020.05.18 |