티스토리 뷰

앞서 @Autowired를 통해 의존 자동 주입을 하는 코드와 DI에 대해 알아보았다.

이번엔 실질적으로 @Autowired의 사용법을 자세히 다뤄보겠다.

 

Config.class
A.class
B.class

Config 클래스를 자세히 들어다보자.

이 클래스에선 의존 대상을 설정 코드에서 직접 주입한다. 이렇게 의존 대상을 설정 코드에 직접 주입하지 않고 스프링이 자동으로 의존하는 빈 객체를 주입하는 기능도 있다.  이를 자동 주입이라고 한다.

 

자동주입을 설정하려면 @Autowird 또는 @Resource 어노테이션을 사용하면 된다.

이 책에서는 @Autowird만 설명한다.

 

그럼 저 클래스를 어떻게 바꿔야 할까! 

답은 간단하다.

 

바뀐 클래스들.

 

A 클래스는 변동사항이 없다. 바뀐 것은 Config , B 클래스이다.

자세히 살펴보면 Config 클래스에 b( )메서드에서 B 인스턴스를 만들 때 인자를 전달하지 않은 것을 볼수 있다.

B클래스는 A 필드에 @Autowired를 붙임으로써 설정 클래스에 의존 주입 코드를 삭제한 것이다.

 

@Autowired 어노테이션은 메서드에도 붙일 수 있다.

 

B 클래스

 

바뀐 클래스는 B 밖에 없고 세터메서드를 통해 의존 자동 주입을 하고있다. 실제로 돌려보면 에러없이 잘 작동한다.

이는 빅 객체의 메서드에 @Autowired 어노테이션을 붙이면, 스프링은 해당 메서드를 호출한다. 이때 메서드 파라미터 타입에 해당하는 빈 객체를 찾아 인자로 주입한다.

 

이렇듯 스프링 @Autowired 어노테이션을 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입한다는 것.

 

 

그렇다면 일치하는 빈이 없는 경우 어떻게 될까?

즉 Config 클래스에 A라는 빈 객체를 코딩하지 않았다면 예상한대로 역시 Exception이 발생한다.

 

Exception 발생.

Exception에 대한 내용은 필드에 대한 의존을 충족하지 않는다와 적용할 수 없는 A라는 빈 타입이 없다라는 내용이다.

결론은 B라는 빈 객체에 A라는 빈객체를 주입할 수 없어서 나오는 에러이다.

 

A라는 빈 객체 2개!?

 

그럼 또다른 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라는 어노테이션을 사용해 자동 주입할 빈을 지정할 수 있는 방법을 제시한다.

 

 

@Qualifier

 

A라는 빈 객체에 @Qualifier를 통해서 이름을 지정한다고 생각하면 편하다.

first_a라는 이름을 지정하고 setter 메서드가 스프링에 의해 호출될 때 내가 지정한 first_a라는 A 빈 객체로 가라고 하면 스프링은 혼동하지 않고 우리가 지정한 빈 객체로 들어가는 것이다.

 

실행해보면 에러가 나지 않는 것을 확인할 수 있다.

 

 

그럼 @Qualifier 어노테이션이 없으면 어떻게 될까? 그냥 빈의 이름을 한정자로 지정한다. 메서드이름이 빈의 이름이다.무슨 뜻일까? 밑에 코드를 보면 이해가 바로 갈 것이다.

Qualifier("a1")

앞서 Config 클래스에서 A 빈 객체를 만드는 메서드의 이름이 a1이었다. B 클래스는 a1이라는 이름을 따서 @Qualifier를 하면 a1 빈객체로 이동하는 것이다.

 

당연히 에러는 나지 않는다.

 

 

그럼 @Autowird 어노테이션의 필수 여부에 대해 생각해보자.

 

 

A 빈 객체가 사라진 Config class

 

아까 실행했듯이, A라는 빈 객체가 사라지면 입셉션 에러가 났다. 그런데 자동 주입할 대상이 필수가 아닌 경우가 존재할 것이다. 그럼 어떻게 해야 이것을 타개할 수 있을까?

 

3가지 방법이 있다.

 

1)@Autowired(required=false)

필드나 세터메서드에 매칭되는 빈이 없어도 입셉션이 발생하지 않으며 자동 주입을 수행하지 않는다.

required=false

 

2) 스프링 5버전 이후 자바 8의 Optional 사용가능 :  A라는 빈 객체가 존재하면 세팅한다.

Optional<Class>

 

3) @Nullable 어노테이션

@Nullable

 

 

이렇게 3가지 방법을 실행해서 A라는 빈객체를 삭제하더라도 B 빈 객체에 A 필드는 null 값이 들어가며 입셉션이 발생하지 않는다.

 

 

고찰)

그렇다면 마지막으로 생각해봐야 하는 것은 스프링의 자동 주입과 처음에 했던 명시적 의존 주입 간의 관계이다.

즉 설정 클래스에서 의존을 주입했는데 자동 주입 대상이면? 자동 주입이 우선시 되는 현상을 알아 볼 수 있다!

따라서 @Autowird 어노테이션을 이미 사용했다면 설정 클래스에 굳이 명시적으로 객체를 주입시키기 보다 스프링이 제공하는 자동 주입 기능을 사용하는 것이 낫다.

 

자동 주입과 명시적 주입의 코드가 섞여있다면 주입의 방향성이 어긋나 NullPointerException이 발생했을 때 원인 찾는데 시간이 걸릴 수 있으니 의존 자동 주입의 사용을 일관되게 사용해야한다. 일부 자동 주입을 적용하기 어려운 코드를 제외한 나머지 코드는 의존 자동 주입을 사용하자는 것이 저자의 지론이다.

 

 

여기까지해서 의존 자동 주입에 대해 설명했다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함