티스토리 뷰
앞서 @Autowired를 통해 의존 자동 주입을 하는 코드와 DI에 대해 알아보았다.
이번엔 실질적으로 @Autowired의 사용법을 자세히 다뤄보겠다.
Config 클래스를 자세히 들어다보자.
이 클래스에선 의존 대상을 설정 코드에서 직접 주입한다. 이렇게 의존 대상을 설정 코드에 직접 주입하지 않고 스프링이 자동으로 의존하는 빈 객체를 주입하는 기능도 있다. 이를 자동 주입이라고 한다.
자동주입을 설정하려면 @Autowird 또는 @Resource 어노테이션을 사용하면 된다.
이 책에서는 @Autowird만 설명한다.
그럼 저 클래스를 어떻게 바꿔야 할까!
답은 간단하다.
A 클래스는 변동사항이 없다. 바뀐 것은 Config , B 클래스이다.
자세히 살펴보면 Config 클래스에 b( )메서드에서 B 인스턴스를 만들 때 인자를 전달하지 않은 것을 볼수 있다.
B클래스는 A 필드에 @Autowired를 붙임으로써 설정 클래스에 의존 주입 코드를 삭제한 것이다.
@Autowired 어노테이션은 메서드에도 붙일 수 있다.
바뀐 클래스는 B 밖에 없고 세터메서드를 통해 의존 자동 주입을 하고있다. 실제로 돌려보면 에러없이 잘 작동한다.
이는 빅 객체의 메서드에 @Autowired 어노테이션을 붙이면, 스프링은 해당 메서드를 호출한다. 이때 메서드 파라미터 타입에 해당하는 빈 객체를 찾아 인자로 주입한다.
이렇듯 스프링 @Autowired 어노테이션을 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입한다는 것.
그렇다면 일치하는 빈이 없는 경우 어떻게 될까?
즉 Config 클래스에 A라는 빈 객체를 코딩하지 않았다면 예상한대로 역시 Exception이 발생한다.
Exception에 대한 내용은 필드에 대한 의존을 충족하지 않는다와 적용할 수 없는 A라는 빈 타입이 없다라는 내용이다.
결론은 B라는 빈 객체에 A라는 빈객체를 주입할 수 없어서 나오는 에러이다.
그럼 또다른 Exception case를 생각해보자.
주입 대상에 일치하는 빈이 두개라면? 어떻게 될까?
Error creating bean with name 'b': Unsatisfied dependency expressed through method 'setA' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
기존 에러 내용의 핵심만 따왔다.
해석을 해보면 B라는 빈 객체를 만드려는데 주입 조건이 만족하지 않아. 그건 유니크한 빈이 없기때문이야! 라는 메시지를 준다.
그렇다면 이 각각의 타입이 값은 빈 객체를 사용할 수는 없는걸까?
스프링은 @Qualifier라는 어노테이션을 사용해 자동 주입할 빈을 지정할 수 있는 방법을 제시한다.
A라는 빈 객체에 @Qualifier를 통해서 이름을 지정한다고 생각하면 편하다.
first_a라는 이름을 지정하고 setter 메서드가 스프링에 의해 호출될 때 내가 지정한 first_a라는 A 빈 객체로 가라고 하면 스프링은 혼동하지 않고 우리가 지정한 빈 객체로 들어가는 것이다.
실행해보면 에러가 나지 않는 것을 확인할 수 있다.
그럼 @Qualifier 어노테이션이 없으면 어떻게 될까? 그냥 빈의 이름을 한정자로 지정한다. 메서드이름이 빈의 이름이다.무슨 뜻일까? 밑에 코드를 보면 이해가 바로 갈 것이다.
앞서 Config 클래스에서 A 빈 객체를 만드는 메서드의 이름이 a1이었다. B 클래스는 a1이라는 이름을 따서 @Qualifier를 하면 a1 빈객체로 이동하는 것이다.
당연히 에러는 나지 않는다.
그럼 @Autowird 어노테이션의 필수 여부에 대해 생각해보자.
아까 실행했듯이, A라는 빈 객체가 사라지면 입셉션 에러가 났다. 그런데 자동 주입할 대상이 필수가 아닌 경우가 존재할 것이다. 그럼 어떻게 해야 이것을 타개할 수 있을까?
3가지 방법이 있다.
1)@Autowired(required=false)
필드나 세터메서드에 매칭되는 빈이 없어도 입셉션이 발생하지 않으며 자동 주입을 수행하지 않는다.
2) 스프링 5버전 이후 자바 8의 Optional 사용가능 : A라는 빈 객체가 존재하면 세팅한다.
3) @Nullable 어노테이션
이렇게 3가지 방법을 실행해서 A라는 빈객체를 삭제하더라도 B 빈 객체에 A 필드는 null 값이 들어가며 입셉션이 발생하지 않는다.
고찰)
그렇다면 마지막으로 생각해봐야 하는 것은 스프링의 자동 주입과 처음에 했던 명시적 의존 주입 간의 관계이다.
즉 설정 클래스에서 의존을 주입했는데 자동 주입 대상이면? 자동 주입이 우선시 되는 현상을 알아 볼 수 있다!
따라서 @Autowird 어노테이션을 이미 사용했다면 설정 클래스에 굳이 명시적으로 객체를 주입시키기 보다 스프링이 제공하는 자동 주입 기능을 사용하는 것이 낫다.
자동 주입과 명시적 주입의 코드가 섞여있다면 주입의 방향성이 어긋나 NullPointerException이 발생했을 때 원인 찾는데 시간이 걸릴 수 있으니 의존 자동 주입의 사용을 일관되게 사용해야한다. 일부 자동 주입을 적용하기 어려운 코드를 제외한 나머지 코드는 의존 자동 주입을 사용하자는 것이 저자의 지론이다.
여기까지해서 의존 자동 주입에 대해 설명했다.
'책 > 초보 웹 개발자를 위한 스프링5 프로그래밍 입문' 카테고리의 다른 글
7장. AOP 프로그래밍 (0) | 2021.10.08 |
---|---|
6장. 빈 라이프사이클과 범위 (0) | 2021.10.05 |
5장. 컴포넌트 스캔 (0) | 2021.10.03 |
3강. 스프링 DI (0) | 2021.09.30 |
2강. 스프링 시작. (0) | 2021.09.30 |
- Total
- Today
- Yesterday
- ㄴ
- https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html
- https://jwprogramming.tistory.com/52
- https://velog.io/@juno7803/React%EA%B0%80-%ED%83%9C%EC%96%B4%EB%82%9C-%EB%B0%B0%EA%B2%BD
- https://react.vlpt.us/basic/11-render-array.html
- https://react.vlpt.us/
- https://wikidocs.net/68
- Co
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |