[Spring] ResourceLoader

joyful·2021년 8월 28일
0

Java/Spring

목록 보기
18/28
post-thumbnail

1. ResourceLoader

1.1 개요

  • 리소스를 읽어오는 기능을 제공하는 인터페이스
    • 파일 시스템에서 읽어오기
    • classpath에서 읽어오기 ex) "classpath:test.dat"
      (default : target/classed)
    • URL로 읽어오기 ex) "file:C:/test.dat"
    • 상대/절대 경로로 읽어오기 ex) "WEB-INF/test.dat"
  • 리소스의 경로를 보고 적절한 Resource 구현 클래스를 사용하고, 개발자에게 Resource Type 객체를 반환해줌
  • Resource 및 Resource[] 유형의 Bean 속성은 특정 컨텍스트의 리소스 로드 전략을 사용
    ApplicationContext에서 실행할 때 문자열로 채울 수 있음
  • ApplicationContext를 통해서도 ResourceLoader에서 제공하는 메서드 사용 가능


1.2 사용 방법

  • Resource getResource(String location)
    • 지정된 리소스 위치에 대한 Resource 타입 반환
    • resources 폴더 안의 리소스를 읽음
@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    ResourceLoader resourceLoader;
    //ApplicationContext resourceLoader;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Resource resource = resourceLoader.getResource("classpath:test.txt");
        System.out.println(resource.exists());  //resource 존재 확인
        System.out.println(resource.getDescription());
        System.out.println(resource.getFile()); //파일 객체
        System.out.println(resource.getFilename()); //파일 이름
        System.out.println(resource.getInputStream()); //InputStream 객체
        System.out.println(resource.getURI().getPath()); //URL 객체
    }
}


2. Resource 추상화

Resource 인터페이스

  • java.net.URL 클래스를 org.springframework.core.io.Resource 클래스로 감싸서 실제 low level에 있는 Resource에 접근하는 기능을 만든 것

    💡 java.net.URL

    웹 상에 존재하는 자원에 접근할 때 사용하는 클래스

  • 스프링 내부에서 많이 사용하는 인터페이스

✅ 추상화 하는 이유

  • classpath를 기준으로 리소스를 읽어오는 기능 부재
    → 다른 방법으로도 리소스를 읽어올 수 있지만, spring에서 리소스를 읽어오는 방법을 통일시키기 위해 classpath 기준으로 리소스를 읽어오도록 한 것임
  • ServeletContext를 기준으로 상대 경로로 읽어오는 기능 부재
  • 새로운 핸들러를 등록하여 URL 접미사를 만들어 사용할 수 있지만, 구현이 복잡하고 편의성 메서드가 부족함

✅ 주요 메서드

종류설명
getInputStream()◾ 리소스의 위치를 찾고 오픈한 뒤, 리소스를 읽기 위한 InputStream을 Return
◾ 호출할 때마다 새로운 객체를 Return
◾ 스트림을 닫는 것은 호출한 쪽에 책임이 있음
exists()해당 리소스 존재 여부에 따른 논리값 Return
isOpen()◾ 해동 리소스가 오픈 스트림을 가진 하나의 핸들을 나타내는지에 대한 논리값 Return
◾ true일 경우, InputStream은 반드시 한번만 읽은 후 닫아주어야 함
  (여러번 읽을수 없음)
InputStreamResource 예외를 가진 일반적인 리소스 구현체에서는 false
getDescription◾ 해당 리소스에 대한 설명 Return
◾ 정규화 된 파일명, 리소스의 실제 URL

Resource 구현체

종류설명
UrlResource◾ URL 상의 웹 리소스를 다루기 위한 클래스
java.net.URL을 wrapping하고 일반적으로 URL로 접근할 수 있는 파일
◾ http, https, ftp, file, jar 프로토콜을 기본으로 지원
ClassPathResource◾ classpath 상의 리소스를 다루기 위한 클래스
◾ 접두어 classpath: 지원
◾ Thread Context Loader, ClassLoader, Class Load 시 주어진 클래스를 모두 사용
◾ 파일 시스템에 존재 시 java.io.File과 같은 해결책 지원
◾ jar에 존재하는 클래스패스
  - 리소스 지원 x
  - 파일 시스템으로 확장 x
PathResourcejava.nio.file 패키지를 사용해 파일 시스템 상의 리소스를 다루기 위한 클래스
◾ classpath 상의 리소스를 다루기 위한 클래스
◾ 접두어 classpath: 지원
FileSystemResourcejava.io 패키지를 사용해 파일 시스템 상의 리소스를 다루기 위한 클래스
◾ 접두어 file:/// 지원
ServletContextResource◾ 웹 애플리케이션 루트에서 상대 경로로 리소스 조회
◾ 기본값
◾ 읽어들이는 Resource Type이 ApplicationContext Type에 따라 결정
   → 가장 많이 사용
InputStreamResourceInputStream에 대한 구현체
◾ 적용 가능한 특정 Resource 구현체가 없을 때만 사용 가능
ByteArrayResource나 파일 기반 Resource 구현체가 가능한 곳에서 선호
◾ 다른 구현체와 달리 이미 오픈된 Resource에 대한 discriptor
   → isOpen() : true 리턴
ByteArrayResourceByte 배열에 대한 구현체
◾ 주어진 바이트 배열에서 컨텐츠 로드시 유용

✅ 리소스 조회

📝 Resource 타입 결정

  • location 문자열과 ApplicationContext 타입에 의해 결정 됨

    ApplicationContext 타입Resource 타입
    ClassPathXmlApplicationContextClassPathResource
    FileSystemXmlApplicationContextFileSystemResource
    WebApplicationContextServletContextResource
  • java.net.URL 접두어(+classpath:) 중 하나 사용
    ApplicationContext 타입에 상관 없이 리소스 타입 강제

    • classpath:/me/corn/config.xmlClassPathResource
    • file://some/resource/path/config.xmlFileSystemResource

📝 주의사항

  • 보통 웹 애플리케이션을 개발하므로, ApplicationContext를 주입받아서 Resource를 조회하면 ServletContextResource를 사용하게 됨
    (웹 애플리케이션 루트 경로에서 시작해서 리소스를 조회)
  • classpath에 존재하는 리소스를 조회하길 원할 경우, Resource를 조회할 때 접두어 classpath:를 붙여줘야 함



📖 참고

profile
기쁘게 코딩하고 싶은 백엔드 개발자

0개의 댓글