@Resource 활용 팁

스프링에서 @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>

이렇게 추가해주면 끝..

Resource를 속성으로 가지는 클래스

Resource로 사용할 파일의 이름이나 위치가 자주 바뀌는 경우에 Resource 타입의 변수를 가지고 있는 클래스의 속성을 configuration 파일에 설정 해두는 것이 편할 수 있습니다.

public class PlainResourceHolder {
    private Resource resource;

    public Resource getResource() {
        return resource;
    }

    public void setResource(Resource resource) {
        this.resource = resource;
    }
}

이렇게 Resource를 가지고 있는 클래스가 있을 때 설정 파일에서도 prefix를 사용해서 Resourc에 값을 넣어 줄 수 있습니다.

<bean id=”holder2″ class=”resource.PlainResourceHolder”>
        <property name=”resource” value=”file:resourceTest.txt” />
</bean>

다음과 같이 테스트를 해보면 원하는 대로 일이 처리 된 걸 확인할 수 있습니다.

    @Test public void resourceFromConfiguration(){
        PlainResourceHolder holder = (PlainResourceHolder)context.getBean(“holder2”);
        Resource resource =  holder.getResource();
        assertTrue(resource.exists());
        assertTrue(resource.getFilename().equals(“resourceTest.txt”));
    }

Resource, ResourceLoader 인터페이스 사용 예

간단한 테스트 코드를 작성해 봤습니다.

@Test public void resource(){
        Resource resource = context.getResource(“resourceTest.txt”);
        assertTrue(resource.exists());
    }

ApplicationContext를 ResourceLoader로 사용할 수도 있기 때문에 getResource를 통해서 Resource객체를 받을 수 있습니다.

사용자 삽입 이미지resourceTest.txt 파일의 위치가 위 와 같을 때.. 위의 테스트 코드는 빨간불이 들어옵니다. 대시 file: 이라는 prefix를 붙여 주면 녹색 불이 들어옵니다.

    @Test public void resource(){
        Resource resource = context.getResource(“file:resourceTest.txt”);
        assertTrue(resource.exists());
    }

getResource의 인자로 넘기는 문자열 값에 붙일 수 있는 prefix에는 다음과 같은 것들이 있습니다.

Prefix Example Explanation

classpath:

classpath:com/myapp/config.xml

Loaded from the classpath.

file:

file:/data/config.xml

Loaded as a URL, from the
filesystem. [a]

http:

http://myserver/logo.png

Loaded as a
URL.

(none)

/data/config.xml

Depends on the underlying
ApplicationContext.

아무것도 안붙인 상태에서 에러가 발생한 이유는 현재 사용중인 ApplicationContext가 ClassPathXmlApplicationContext 이녀석이기 때문에 classpath: 를 붙인 것 처럼 동작했기 때문입니다.