Resource 추상화

de_sj_awa·2021년 6월 25일
0
post-custom-banner

org.springframework.core.io.Resource

특징

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

추상화 한 이유

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

실질적으로 내부에서는 모두 리소스를 사용한다.

@Component
public class AppRunner implements ApplicationRunner {
    /*
    @Autowired
    ApplicationContext resourceLoader;
    */

    @Autowired
    ResourceLoader resourceLoader;
    
     @Override
    public void run(ApplicationArguments args) throws Exception {
        var ctx = new ClassPathXmlApplicationContext("abc.xml");
        System.out.println(resourceLoader.getClass());
        Resource resource = resourceLoader.getResource("test.txt");
        //Resource resource = resourceLoader.getResource("classpath:test.txt");
        System.out.println(resource.getClass());
        System.out.println(resource.exists()); System.out.println(Files.readString(Path.of(resource.getURI())));
    }
}

var ctx = new ClassPathXmlApplicationContext("xxx.xml"); (클래스패스 기준) 이나 var ctx = new FileSystemXmlApplicationContext("xxx.xml"); (파일시스템 경로 기준) 을 쓰면 자동으로 내부적으로는 Resource resource = resourceLoader.getResource("xxx.xml"); 으로 변환되는 것이다.

인터페이스 둘러보기

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

구현체

  • UrlResource: java.net.URL 참고, 기본으로 지원하는 프로토콜 http, https, ftp, file, jar.
  • ClassPathResource: 지원하는 접두어 classpath:
  • FileSystemResource
  • ServletContextResource: 웹 애플리케이션 루트에서 상대 경로로 리소스 찾는다. (사실상 가장 많이 쓰임 그 이유는 아래와 같다.)
  • ...

리소스 읽어오기

  • Resource의 타입은 locaion 문자열과 ApplicationContext의 타입에 따라 결정 된다. (ResourceLoader 또한 ApplicationContext가 구현함)
    - ClassPathXmlApplicationContext -> ClassPathResource
    - FileSystemXmlApplicationContext -> FileSystemResource
    - WebApplicationContext -> ServletContextResource
  • ApplicationContext의 타입에 상관없이 리소스 타입을 강제하려면 java.net.URL 접두어(+ classpath:)중 하나를 사용할 수 있다.
    - classpath:me/whiteship/config.xml -> ClassPathResource
    - file:///some/resource/path/config.xml -> FileSystemResource

확인하는 방법


@Component
public class AppRunner implements ApplicationRunner {
    
    @Autowired
    ApplicationContext resourceLoader;

    /*
    @Autowired
    ResourceLoader resourceLoader;
    */

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(resourceLoader.getClass());
        Resource resource = resourceLoader.getResource("classpath:test.txt");
        System.out.println(resource.getClass());
        System.out.println(resource.exists());
        System.out.println(resource.getDescription());
        System.out.println();
        System.out.println(Files.readString(Path.of(resource.getURI())));
    }
}

그러나 스프링 웹 어플리케이션을 작성할 경우 classpath 기준으로 많은 리소스들을 사용하기 때문에 classpath 접두어를 붙이는 것을 추천한다. 아무 접두어를 붙이지 않으면 ServletContextResource로 resolving 된다.

Resource 추상화에 대한 추가적인 내용은 https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-as-dependencies 에서 확인할 수 있다.

참고

profile
이것저것 관심많은 개발자.
post-custom-banner

0개의 댓글