Whiteship's Note


[스프링 퀴즈] @Autowired

Spring/etc : 2010.06.04 17:30


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class AutowiredTest {

    @Autowired DataSource dataSource;

    @Test
    public void notNull(){
        assertThat(dataSource, is(notNullValue()));
    }

}

위와 같은 테스트가 있다. 위 코드가 있는 곳과 같은 패키지에 AutowiredTest-context.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

1. 이렇게 설정했을 때 테스트는 어떻게 될까? 깨질까? 성공할까?

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

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

2. 이렇게 설정했다면 어떻게 될까?

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

    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

    <bean id="testDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

3. 그럼 이건 어떨까?

셋다 맞춘 분에게 물어보고 싶은 질문이 있는데;; 맞추시는 분께 댓글로 질문 드리겠습니다.
top

  1. Favicon of http://lckymn.com BlogIcon Kevin 2010.06.04 19:41 PERM. MOD/DEL REPLY

    저렇게 해본적이 없어서 확실치는 않지만,
    설정파일이나 설정파일 위치에 문제가 없다는 가정하에
    ("설정파일 위치가 제대로 설정 안돼서 모두 실패" 혹은
    "설정파일의 설정이 잘못돼서 모두 실패" 이런거는 아니라고 가정... ㅡ_ㅡ;
    이거 잘 기억이 안 나거든요. ^^; )
    1. 알아서 타입추론해서 주입돼서 성공
    2. 주입하려는 타입의 instance가 하나 이상 존재해서 테스트 하기 전에 DI하면서 에러
    3. id가 dataSource인 instance가 주입돼서 성공

    SimpleDriverDataSource가 DataSource implementing 하는거 맞죠? :)
    그나저나 혹시 만에 하나 맞더라도 질문은 다음분께 양보하는 미덕을 발휘해 봅니다. :D

    Favicon of http://whiteship.me BlogIcon 기선 2010.06.04 21:13 PERM MOD/DEL

    Kevin님께서 푸시면 어떡합니다~~ㅋㅋ

    원래 드리려고 했던 질문은 왜 id로 먼저 확인안하고 타입으로 먼저 찾아볼까요? 라는 거였는데 집에 오는길에 생각하다가 풀렸습니다.

    id 먼저 확인했다가 그 빈이 원하는 타입이 아니면 또 다시 원하는 타입에 해당하는걸로 찾아봐야 할테니 그냥 애초에 타입으로 먼저 찾는게 id로 먼저 찾아보는 것보다 나은 것 같더라구요.

    Favicon of http://lckymn.com BlogIcon Kevin 2010.06.05 18:38 PERM MOD/DEL

    헉! 제가 풀면 안되는거였나요? @_@; 다음 질문이라도 양보해서 다행... (응?ㅡ_ㅡ?)
    그나저나 맞기는 한건지...ㅡ_ㅡ;
    요즘은 @Configuration 위주로 써서요.
    xml은 security 쪽이랑, db 관련된 쪽만 쓰는데,
    여기서 같은 타입의 객체를 두개이상 만들일이 없어서
    가물가물합니다. :)
    (View도 다 @Configuration 에서 만들어 버립니다. :) )
    아... component scanning 도 xml 쓰는군요.

    @Configuration 에서 같은 타입의 객체를 두개이상
    생성 해야 할경우, 따로 설정하기 보다
    method 이름을 다르게 하고,
    그게 맞게 변수이름을 사용해서 처리하는식으로 써서요.

    Favicon of http://whiteship.me BlogIcon 기선 2010.06.06 22:14 PERM MOD/DEL

    벌써 @Configuration을 애용하고 계시군요.

    얼마전에 트위터인지 버즈에서 링크건 내용 중에 그런게 있더라구요. '사람들은 편한것 보다 익숙한 것을 사용한다.' 였나? 머 그런 비슷한 거였는데.. 그 글을 보면서 공감가는 부분이 많았는데

    @Configruation에 대한 댓글을 보다보니 갑자기 그 글귀가 생각나네요.ㅎ

    사실 저도 같은 타입 빈을 두개씩 등록해서 사용하는 경우는 거의 드물구요. 위 테스트는 @Autoewired 학습 테스트 정도에 해당하겠네요.

    @Autowired가 "타입으로 자동주입" 이라는 생각으로 굳어져있었거든요. 그래서 내심 세번째 경우도 에러가 나지 않을까하고 확인해본것인데 잘 되더라구요.ㅋㅋ

Write a comment.


BeanLifeCycle 인터페이스를 없애보자.

Spring/Chapter 3 : 2008.09.22 16:50


BeanLifeCycle에 등장하는 여러 인터페이스 들 중에서 BeanFactoryAware, ApplicationContextAware, MessageSoruceAware, ApplicationEventPublisherAware, ResourceLoaderAware 인터페이스를 사용하지 않고도 이들이 해주는 일과 똑같은 작업을 할 수 있습니다.

@Component
public class Bean {

    @Autowired
    ApplicationContext applicationContext;
   
    @Autowired
    MessageSource messageSource;
   
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    ResourceLoader resourceLoader;
   
    @Autowired
    BeanFactory beanFactory;
   
}

이런식으로 @Autowired를 사용하시면 됩니다. 물론 저 중에서 BeanFactory를 뺀 나머지는 ApplicationContext를 사용할 때 이용할 수 있겠죠. 라이프사이클 중에 InitializingBean 인터페이스는 bean 엘리먼트의 init-method 또는 @PostConstruct를 사용하면 대체할 수 있습니다.

꼭 필요하진 않고, 있을 때만 주입하고 싶다면, @Autowired(required=false) 이렇게 설정하면 되겠죠.

다음은 위 코드의 테스트 코드입니다,.

@ContextConfiguration(locations="springContext.xml")
public class BeanTest extends AbstractJUnit4SpringContextTests{

    @Autowired
    Bean bean;
   
    @Test
    public void lifecycle() {
        assertNotNull(bean.beanFactory);
        assertNotNull(bean.applicationContext);
        assertNotNull(bean.messageSource);
        assertNotNull(bean.applicationEventPublisher);
        assertNotNull(bean.resourceLoader);
    }
   
}

테스트는 당연히 잘 돌아갑니다.

아차. 빈 설정파일은 딱 두 줄 한 줄 입니다.
    <context:component-scan base-package="org.opensprout.sandbox.lifecycle" />
   
    <context:annotation-config />

top

  1. Favicon of http://toby.epril.com BlogIcon '토비 2008.09.22 18:27 PERM. MOD/DEL REPLY

    XML 설정에 문제가 있꾼!

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.09.22 22:27 신고 PERM MOD/DEL

    헉;;; 한줄로 줄일 수 있군요.

    context:component-scan 이 엘리먼트 등록하면 <context:annotation-config /> 얘도 등록한셈이 되는거죠.

    ㅎㅎ감사합니다.

Write a comment.


@Resource 활용 팁

모하니?/Coding : 2008.09.08 13:41


스프링에서 @Autowired와 @Resource. 이 둘의 가장 큰 차이는 하나는 by-type이고, 하나는 by-name이라는 것. 주로 @Autowired를 사용해서 보통 다음과 같이 코딩합니다.

public class Post {

   @Autowired private Cate cate;
   ...
}

그런데 만약에 Cate 타입이 두 종류라면.. MainCate, SubCate. 이렇게 나눴다고 치고 위의 코드를 실행하면 에러가 닙니다. NoSuchBean뭐시기 Exception이 나면서 해당 타입의 빈이 1개가 아니다. 라는 예외가 발생하요. 그럴 때 처방으로 보통..

public class Post {

  @Autowired @Qulifier("mainCate")
  private Cate maincate
  ...

}

이렇게 @Qulifier를 사용하곤 하는데.. 사실 저걸 @Resource로 바꾸면 굉장히 간단해집니다.

public class Post {

  @Resource private Cate maincate
  ...

}


캬~~ 간단하죠. @Resource 애노테이션을 사용하려면 jsr250-api.jar 파일을 추가해주면 됩니다. 메이븐을 사용하고 있다면

        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>

이렇게 추가해주면 끝..

'모하니? > Coding' 카테고리의 다른 글

DisplayTag 데코레이터 사용하기  (0) 2008.09.29
OSAF 검색 폼 태그 파일 완성  (0) 2008.09.25
Principle of least astonishment  (0) 2008.09.24
How to Design a Good API & Why it Matters  (0) 2008.09.24
delete 요청 처리 컨트롤러 코드 고민  (0) 2008.09.22
@Resource 활용 팁  (6) 2008.09.08
TDDBE - xUnit 23장  (0) 2008.09.01
TDDBE - xUnit 22장  (0) 2008.09.01
TDDBE - xUnit 21장  (0) 2008.09.01
TDDBE - xUnit 20장  (0) 2008.09.01
TDDBE - xUnit 19장  (2) 2008.09.01
top

  1. Favicon of http://kirigun.tistory.com BlogIcon 키리군 2008.09.09 17:56 PERM. MOD/DEL REPLY

    안녕하세요~

    질문이 있는데요.

    스프링 2.5에서 annotation을 이용해서 controller를 사용하려는데,

    @Controller
    public class NewsAction
    {
    @Autowiredprivate NewsDAO newsDAO;

    @Autowired 부분에서 No unique bean of type 이라고 하는 exception이 발생하는데

    도통 이유를 모르겠네요.. 혹시 이런 경험있으시면 조언 부탁드립니다.

    아..DAO는 sqlmap을 연동해서 구현되었습니다..

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.09.09 21:59 PERM MOD/DEL

    크핫. 그 에러가 바로 위에서 언급한 그 에러 입니다. 다음을 확인해보세요.

    1. NewsDAO 타입의 빈이 두 개 이상인지..
    2. NewsDAO를 혹시 빈으로 등록 안하진 않았는지..

    이 두 가지도 아니면 설정파일을 잘 보고, 컴포넌트 스캔을 사용하고 계시다면, 디폴트 패키지 위치를 어디로 했는지 확인해서 확실하게 NewsDAO가 빈 스캔너한테 걸리게 되어 있는건지 확인해보세요.

  2. Favicon of http://kirigun.tistory.com BlogIcon 키리군 2008.09.09 23:43 PERM. MOD/DEL REPLY

    설정파일에 컴포넌트 스캔을 사용합니다.

    xxx-servlet.xml 에는 com.ds.action 으로 정의해놓았구요(위에 질문한 action class들입니다)

    context.xml 쪽에는 com.ds.dao 패키지로 정의해두었습니다.

    servlet은 정상적으로 검색이 되는데 유독 멤버로 선언한 dao부분에서 에러가 나네요;;

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.09.10 08:40 PERM MOD/DEL

    스트럿츠 사용하시나요? 액션이란 용어를 쓰시는군요. :)
    흠.. 그럼 일단 @Qulifier나 @Resource로 해당 빈 이름을 줘서 by-name으로는 잘 가져오나 확인해보세요. 그래도 안 되면 빈 설정에 문제가 있거나, DAO가 필요로 하는 다른 빈을 만들지 못해서 그럴 수도 있으니까요.

    http://forum.ksug.org

    여기에 에러 로그랑 설정 파일 같이 올려주시면 좋겠습니다.

  3. Favicon of http://kirigun.tistory.com BlogIcon 키리군 2008.09.16 17:21 PERM. MOD/DEL REPLY

    포럼에 질문글 올렸습니다.

    급한맘에 되는 설정으로 잠시 돌리다가

    spring security쪽에서 또 삽질하고 있네요..ㅠㅠ

    정말 지푸라기라도 잡고 싶은 심정입니다.. 내일까진 설정완료해야 될텐데..쩝;;

    어렵네요..

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.09.16 22:08 PERM MOD/DEL

    네;; 전 오늘 어디 다녀오느라 이제 댓글을 봤습니다. 다른 분들이 도와주고 계시네요. :)

Write a comment.