Resource 추상화

맹기·2021년 3월 25일
0

Spring 핵심 기술 원리

목록 보기
12/19

org.springframework.io.Resource

1. 특징

  • java.net.URL을 추상화 한 것.
  • 스프링 내부에서 많이 사용하는 인터페이스.

2. 추상화 한 이유

  • 클래스패스 기준으로 리소스 읽어오는 기능 부재
  • ServletContext를 기준으로 상대 경로로 읽어오는 기능 부재
  • 새로운 핸들러를 등록하여 특별한 URL 접미사를 만들어 사용할 수는 있지만 구현이 복잡하고 편의성 메소드가 부족하다.

3.인터페이스 들러보기

  • 상속 받은 인터페이스
  • 주요 메소드
    • getInputStream()
    • exitst()
    • isOpen()
    • getDescription(): 전체 경로 포함한 파일 이름 또는 실제 URL

4. 구현체

  • UrlResource: java.net.URL 참고, 기본으로 지원하는 프로토콜 http, https, ftp, file, jar.
  • ClassPathResource: 지원하는 접두어 claspath:
  • FileSystemResource
  • ServletContextResource : 웹 애플리케이션 루트에서 상대 경로로 리소스 찾는다.
  • ...

5. 리소스 읽어오기

  • Resource의 타입은 locaion 문자열과 ApplicationContext의 타입에 따라 결정 된다.
    • ClassPathXmlApplicationContext -> ClassPathResource
    • FileSystemXmlApplicationContext -> FileSystemResource
    • WebApplicationContext -> ServletContextResource

6. Resource 추상화 관련 연습 코드

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext resourceLoader;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // >> class org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
        System.out.println(resourceLoader.getClass());

        // 1. "classpath:" 라는 prefix를 줬을 경우
        Resource resource = resourceLoader.getResource("classpath:test.txt");
        System.out.println(resource.getClass()); // class org.springframework.core.io.ClassPathResource
        System.out.println(resource.exists()); // true

        // 2. prefix를 주지 않았을 경우 에는, ServletContextResource
        // >> 기본적으로 ServletContextResource가 되기 때문에 context path 부터 resource를 찾게된다.
        // >> 그러나 스프링 부트 톰캣의 context path에는 경로가 지정되어 있지 않기 때문에 resource를 찾을 수 없기 때문에 false.
        // classpath를 항상 꼭 명시 해주는게 좋다.
        resource = resourceLoader.getResource("test.txt");
        System.out.println(resource.getClass()); // class org.springframework.web.context.support.ServletContextResource
        System.out.println(resource.exists()); // false
    }
}

0개의 댓글