강좌/Spring 3.0

006. 스프링을 통한 의존성 주입 - @Autowired vs @Resource vs <property>

여름나라겨울이야기 2013. 1. 17. 23:58
728x90

지난 강좌 딱 한달 + 10일이 지났군요.  한달 10일 기념 이벤트성 글은 아니고요.

바로 이전 강좌 댓글 7개!!! 오오.. 행운의 세븐 기념 이벤트성 글입니다. ^^

 

@Autowired 와 @Resource 어너테이션은 이전 강좌에서 보신 대로 두 객체 사이에 의존성을 해결해 주는 완소 존재입니다.  이 둘을 살짝 비교해보도록 하겠습니다.

 

 

 @Autowired

@Resource 

 제공자

 SpringFramework 

 표준 Java 

 소속 패키지

 org.springframework

 .beans.factory.annotation

 .Autowired

 javax.annotation.Resource

 bean 검색

 byType 먼저, 못 찾으면 byName 

 byName 먼저, 못 찾으면 byType

 특이사항

 

 byName

 강제하기

 @Qualifier("") 협업 

 

 @Autowired
 @Qualifier("tire1")

 name 어트리뷰트

 

 @Resource(name="tire1")

 

표 보고 모르시겠죠. ^^

코드로 이해해 보도록 하겠습니다.

이제부터의 코드는 기존은 expert005 패키지의 Car.java 와 expert.xml 을 이리 저리 바꾸어 가면서 진행하시면 됩니다.  물론 저는 expert006 패키지를 생성했지만요. ^^

 

변경되지 않는 소스 파일은 안 보여드립니다.

 

CASE STUDY 1. xml - bean no id / only 1 tire interface bean

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.1.xsd">

 <context:annotation-config />
 
 <bean class="expert006.KoreaTire"></bean>

 

 <bean id="car" class="expert006.Car"></bean>
</beans>

 

@Resource 의 경우 Car.java

package expert006;

import javax.annotation.Resource;

public class Car {
 @Resource
 Tire tire;

 public String getTireBrand() {
  return "장착된 타이어: " + tire.getBrand();
 }
}

 

@Autowired 의 경우 Car.java

package expert006;

import org.springframework.beans.factory.annotation.Autowired;

public class Car {
 @Autowired
 Tire tire;

 public String getTireBrand() {
  return "장착된 타이어: " + tire.getBrand();
 }
}

 

각각의 경우 Driver.java 를 실행해 보시면 둘 다 아무 문제 없이 잘 실행되는 것을 확인할 수 있습니다.

 

 

CASE STUDY 2. xml - no id / 2 beans

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

 <bean class="expert006.KoreaTire"></bean>

 <bean class="expert006.AmericaTire"></bean>

 

  <bean id="car" class="expert006.Car"></bean>
</beans>

 

@Resource 의 경우 Driver.java 실행 오류 메시지

No unique bean of type [expert006.Tire] is defined:

expected single matching bean but found 2: [expert006.KoreaTire#0, expert006.AmericaTire#0]

 

@Autowired 의 경우 Driver.java 실행 오류 메시지

No unique bean of type [expert006.Tire] is defined:

expected single matching bean but found 2: [expert006.KoreaTire#0, expert006.AmericaTire#0]

 

 

 

CASE STUDY 3. xml - correct id / 2 beans

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

 <bean id="tire" class="expert006.KoreaTire"></bean>

 <bean id="tire2" class="expert006.AmericaTire"></bean>

<bean id="car" class="expert006.Car"></bean>
</beans>

 

@Resource 의 경우 Driver.java 실행 정상 작동

장착된 타이어: 코리아 타이어

 

@Autowired 의 경우 Driver.java 실행 정상 작동

장착된 타이어: 코리아 타이어

 

 

CASE STUDY 4. xml - non correct id / 2 beans

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

<bean id="tire1" class="expert006.KoreaTire"></bean>

<bean id="tire2" class="expert006.AmericaTire"></bean>

<bean id="car" class="expert006.Car"></bean>
</beans>

 

@Resource 의 경우 Driver.java 실행 오류

No unique bean of type [expert006.Tire] is defined:

expected single matching bean but found 2: [tire1, tire2]

 

@Autowired 의 경우 Driver.java 실행 오류

No unique bean of type [expert006.Tire] is defined:

expected single matching bean but found 2: [tire1, tire2]

 

직접 구동해 보셨나요. ^^

완벽하게 일치하는군요.  그럼 둘 중에 어느 것을 써야 할까요?

저는 애정남은 아니지만 Spring 이 제공하는 @Autowired 와 Java 가 제공하는 @Resource 중에서 손 들라고 하면 @Resource 를 밀겠습니다.

자동으로 주입된다는 의미에서는 @Autowired 가 명확해 보이지만 실제 Car 입장에서 보면 @Resource 라는 표현이 더 어울리기도 하지만 향후 Spring 이 아닌 다른 프레임워크가 들어오거나 제거될 때를 고려해 보면 당연히 java 표준인 @Resource 를 써야하는게 더 큰 이유일 겁니다.

 

그럼 여기서 또 고민 @Resource 는 사실 <bean> 태그의 자식 태그인 <property> 태그로 해결될 수 있다는 것 기억 나시죠?  그럼 @Resource vs <property> 에서는 누구의 손을 들어줘야할까요?

<property> 에 저는 손 들겠습니다.  xml 파일만 봐도 DI 관계를 확인하기 수월하기 때문입니다.

그렇지만 개발 생산성은 @Resource 가 빠르겠죠. ^^

유지 보수성은 <property> 가 좋을 것이구요.

프로젝트의 규모가 커지면 xml 파일이 무척 커지게 마련인데 xml 파일도 용도별로 분리할 수 있다느 걸 학습서 등을 보시면 아실 수 있을 겁니다.  그래서 더더욱 <property> 에 한표..

 

애정남 스타일

@Autowird vs @Resource : @Resource 승

@Resource vs <property> : <property> 승 - 다만 프로젝트 규모와 팀에 따라 이건 중용의 도를...

 

그리고 아래는 굳이 알려하지 마세요. 학습서에 잘 나올 겁니다. ^^

 

CASE STUDY 5.

xml - non correct id / 2 beans

@Resource name attribute 

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

<bean id="tire1" class="expert006.KoreaTire"></bean>

<bean id="tire2" class="expert006.AmericaTire"></bean>

<bean id="car" class="expert006.Car"></bean>
</beans>

 

Car.java

package expert006;

import javax.annotation.Resource;

 

public class Car {
  @Resource(name="tire1")
  Tire tire;

 

  public String getTireBrand() {
    return "장착된 타이어: " + tire.getBrand();
  }
}

 

Driver.java 실행 정상 실행

 

 

CASE STUDY 6. case study 5 와 같도록 @Autowird 하려면

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

<bean id="tire1" class="expert006.KoreaTire"></bean>

<bean id="tire2" class="expert006.AmericaTire"></bean>

<bean id="car" class="expert006.Car"></bean>
</beans>

 

Car.java

package expert006;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Car {
@Autowired

@Qualifier("tire1")
Tire tire;

public String getTireBrand() {
return "장착된 타이어: " + tire.getBrand();
}
}

 

Driver.java 실행 정상 실행

 

CASE STUDY 7. 실무라면 저는 이렇게

 

expert.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config />

<bean id="tire" class="expert006.KoreaTire"></bean>

<bean id="tireOther" class="expert006.AmericaTire"></bean>

<bean id="car" class="expert006.Car"></bean>
</beans>

 

Car.java

package expert006;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Car {
@Autowired

@Qualifier("tire")
Tire tire;

public String getTireBrand() {
return "장착된 타이어: " + tire.getBrand();
}
}

 

Driver.java 실행 정상 실행

 

만약 미쿡타이어를 쓰고 싶다면 bean 의 id 만 체인지하겠죠.

 

<bean id="tireOther" class="expert006.KoreaTire"></bean>

<bean id="tire" class="expert006.AmericaTire"></bean>

 

그리고 나서 프로그램을 재구동하면 멋지게 미쿡 타이어가 장착됩니다. 

재컴파일을 필요하지 않습니다(바로 이게 설정 파일을 쓰는 이유 중 가장 중요한 이유일 겁니다.). 

 

마무리

 

이번 강좌는 좀 중구 난방이었던 것 같네요.

 

자 이제 생각나시는 그림이 있으시죠? 있으셔야 하는데...

바로 앞 강좌의 순서도스러운(?) 그림.. 그걸 조금 더 바꾸어 정확하게 그려보세요. 그리고 @Autowird 가 아닌 @Resource 의 입장에서 그려 보세요.  숙제입니다. ^^

숙제 다 하신 분은 저한테 정검을 위해 제출해 주시면 됩니다(저의 흑심이 안 보이길.. )

 

힌트를 드리자면 @Resource 의 name 어트리뷰트가 있을 때와 없을 때 각각의 그림을 그리시는게 건강에 좋을 겁니다. ^^

 

역시 강좌 쓰다보니 새벽이 찾아왔네요.  모두 제 꿈.. 아니 미혼 여성분만 제 꿈 꾸세요. ^^

제 꿈 꾸시고 로또 사신 후에 당청금은 반띵~!!!

 

그럼 주의 은총 가득한 나날들 되시길..

 

다음 강좌는 DI 에 대한 이런 저런 이야기들을 통해 스프링의 3대 핵심 중 하나를 마무리해 보도록 하겠습니다.  3대 핵심이 뭐냐구요?  IoC/DI, AOP, PSA 입니다.

제 Spring 강좌는 스프링 3대 핵심에 대한 초급 강좌입니다. 

중급은 스프링 API 레퍼런스와 책을 보세요,

 

그럼 이제 한달 10일 뒤에 뵐... 댓글 봐서요. ^^

반응형