본문 바로가기
Spring Boot

[Spring Boot] Resource 추상화

by byeongoo 2020. 8. 27.

백기선님의 스프링 핵심 기술 강좌를 들으면서 path에 대한 개념이 헷갈려서 정리하기로 했습니다. Resource에 대해서 살펴보겠습니다.

1. Resource 추상화

스프링에서 java.net.URL을 추상화 한 것이 Resource 인터페이스입니다. 인터페이스를 열어보면 주요 메소드를 볼 수 있습니다. 이렇게 추상화를 한 이유는 클래스패스 기준으로 리소스를 읽어오는 기능의 부재와 ServletContext를 기준으로 상대 경로를 읽어오는 기능 부재 등이 있습니다.

public interface Resource extends InputStreamSource {
    boolean exists();

    default boolean isReadable() {
        return this.exists();
    }

    default boolean isOpen() {
        return false;
    }

    default boolean isFile() {
        return false;
    }

    URL getURL() throws IOException;

    URI getURI() throws IOException;

    File getFile() throws IOException;

    default ReadableByteChannel readableChannel() throws IOException {
        return Channels.newChannel(this.getInputStream());
    }

    long contentLength() throws IOException;

    long lastModified() throws IOException;

    Resource createRelative(String var1) throws IOException;

    @Nullable
    String getFilename();

    String getDescription();
}
  • getInputStream() : 리소스의 위치를 찾고 오픈 뒤 리소스를 읽기 위한 InputStream 리턴. 
  • exists() : 파일의 존재 여부에 따라 boolean 반환
  • isOpen() : 해당 리소스가 오픈 스트림을 가진 하나의 핸들을 나타내는지를 가르키는 booelan 반환
  • getDescription() : 전체 경로 포함한 파일 이름 또는 실제 URL

Resource의 타입은 location 문자열과 ApplicationContext 타입에 따라 결정됩니다. Resouce의 구현체를 몇가지 살펴 보겠습니다.

  • ServletContextResource : 웹 애플리케이션 루트에서 상대 경로로 리소스를 찾는다. 개발자는 잘 인지를 못하지만 가장 많이 사용되는 Resource 구현체이다.
  • UrlResource : java.net.URL을 감싸고 일반적으로 URL로 접근할 수 있는 파일, HTTP 대상, FTP 대상 등과 같은 객체에 접근하는데 사용할 수 있다.
  • ClassPathResource : 클래스패스로부터 리소스를 찾아온다. (접두어로 classpath 사용 가능)
  • FileSystemResource : java.io.File 핸들에 대한 Resource 구현체

ApplicationContext의 타입에 상관없이 리소스 타입을 강제하려면 접두어 (classpath:)를 사용하면 명시적으로 나타낼 수 있습니다. file은 파일 경로로 읽는다는 의미입니다.

classpath:me/whiteship/config.xml -> ClassPathResource
file://some/resource/path/config.xml -> FileSystemResource

 

target/classes 아래가 classpath의 루트라고 생각하면 됩니다. 그 아래에서 test.txt를 찾아오는 것이죠

Resource resource = resourceLoader.getResource("classpath:test.txt");

다른 테스트로는 스프링 웹 어플리케이션 소스에 포함된 정적 자원은 어디서 찾아올까 궁금해서 테스트를 진행해보았습니다. 결론은 기본적으로 static 폴더 아래에서 찾아 왔습니다.

위의 패키지 구조에서 test2.txt라는 정적 자원을 "localhost:8080/test2.txt"에서 찾아오는걸 볼 수 있습니다.