# 2.2 Resource interface

**스프링의 Resource 인터페이스는 저레벨 리소스로 추상화 접근하기 위한 보다 좋은 인터페이스**이다. 아래 리스팅은 Resource 인터페이스 정의를 보여준다.:

> ```java
> public interface Resource extends InputStreamSource {
>
>     boolean exists();
>
>     boolean isOpen();
>
>     URL getURL() throws IOException;
>
>     File getFile() throws IOException;
>
>     Resource createRelative(String relativePath) throws IOException;
>
>     String getFilename();
>
>     String getDescription();
>
> }
> ```

Resource 인터페이스의 정의가 보여주듯이, **InputStreamSource 인터페이스를 확장**한다. 아래는 InputStreamSource 인터페이스의 정의다.

> ```java
> public interface InputStreamSource {
>
>     InputStream getInputStream() throws IOException;
>
> }
> ```

Resource 인터페이스의 가장 중요한 메소드들은 다음과 같다.

* getInputStream() : **리소스를 찾아 열고 InputStream을 반환한다.** 각 호출은 새로운 InputStream을 기대한다. **호출자는 스트림을 닫을 책임이 있다**.
* exists() : 이 리소스가 **실제 물리적으로 존재하는지** boolean값으로 반환한다.
* isOpen() : 이 리소스가 오픈 스트림을 다루는지 boolean값으로 반환한다. 만약 **true이면 InputStream은 여러번 부를 수 없고** 오직 한번 읽어야한다. 그리고 리소스 누수를 피하기 위해 닫는다. InputStreamResource를 제외하고 모든 일반적인 리소스 구현에 대해서는 false를 반환한다
* getDescription() : 리소스를 가지고 작업할 때 **에러가 발생하면 설명을 반환한다**. 이는 종종 완전한 파일명이거나 자원의 실질적인 URL이다.

다른 메소드들은 리소스를 대표하는 URL이나 File 오브젝트를 얻을 수 있다.(만약 기본 구현체가 기능을 지원하고 호환가능하다면)

스프링은 스스로 Resource 추상화는 리소스가 필요할 때 많은 메소드 서명들의 인자 유형으로서 광범위으로 사용한다. 스프링 API의 다른 메소드들은 (예 : 다양한 ApplicationContext 구현의 생성자) 는 코딩되지 않은 또는 간단한 형식으로 해당 컨텍스트 구현에 적합한 리소스를 작성하는 String을 사용하거나 String 경로의 특수 접두사(prefix)를 통해 호출자가 특정 리소스 구현을 생성하고 사용해야한다는 것이다.

Resource 인터페이스가 스프링과, 그리고 스프링에 의해 많이 사용되며, 리소스에 접근하기 위해 비록 코드가 스프링의 다른 일부분에 대해 알지 못하거나 신경쓰지 않더라도 실제적으로 일반 유틸리티 클래스로 본인의 코드에서 사용하는 것은 유용하다. 스프링에 코드를 결합시키는 동안, 정말로 오직 유틸리티 클래스의 작은 set을 결합한다. 그리고 URL을 위해 더 호환 가능한 대체자로서 서비스를 제공하고 이 목적을 위해 사용하는 다른 라이브러리들을 도구화하는 것을 고려할 수 있다.

> Resource 추상은 기능을 대체할 순 없다. 이는 가능하다면 그것을 감싼다. 예를 들어서 UrlResource는 URL을 감싸고 감싸진 URL을 동작하기 위해 사용한다.
