Iyoungman Back-end Developer

스프링 프레임워크 핵심 기술 - Resource 추상화

2020-07-25

정의

import org.springframework.core.io.Resource
  • java.net.URL을 추상화 한 것.


추상화한 이유

  • 클래스패스 기준으로 리소스 읽어오는 기능 부재.
  • ServletContext를 기준으로 상대 경로로 읽어오는 기능 부재.
  • 다양한 방식의 Resource를 동일한 인터페이스로 가져오기 위함이다.


인터페이스

  • Resource : 리소스 접근 API를 추상화해서 Resource라는 인터페이스를 정의.
  • ResourceLoader : 위치를 지정하면 실제 Resource 타입의 객체로 변환해주는 기능 제공.


Resource 주요 구현체

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


리소스 읽어오기

  • ApplicationContext는 ResourceLoader를 상속받고 있다.
  • Resource 타입은 location 문자열과 ApplicationContext의 타입에 따라 결정된다.
  • [1] ClassPathXmlApplicationContext -> ClassPathResource
  • [2] FileSystemXmlApplicationContext -> FileSystemResource
  • [3] WebApplicationContext -> ServletContextResource

  • 기본적으로 WebApplicationContext을 사용한다.
  • 따라서 Resouce의 구현체로 ServletContextResource를 사용한다.


실습 1

@Slf4j
@Component
public class Runner implements ApplicationRunner {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("applicationContext : {}", applicationContext);

        Resource resource = applicationContext.getResource("test.txt");
        log.info("resource : {}", resource);
        log.info("exist : {}", resource.exists());
    }
}
//로그 확인
applicationContext : org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4f209819
resource : ServletContext resource [/test.txt]
exist : false
  • ClassPath에 test.txt 라는 파일을 만들었다.
  • ApplicationContext의 타입은 WebApplicationContext을 상속받는 AnnotationConfigServletWebServerApplicationContext이다.
    따라서 Resouce의 구현체를 ServletContextResource을 사용하고 있다.
    그러므로 ClassPath의 test.txt 파일을 찾을 수 없다.
  • 만약 ApplicationContext의 타입이 ClassPathXmlApplicationContext라면 test.txt 파일을 찾았을 것이다.


ApplicationContext 타입에 상관없이 다양한 리소스 타입을 사용하려면?

  • 접두어를 사용한다.
  • [1] classpath:some/resource/path/config.xml -> ClassPathResource
  • [2] file:///some/resource/path/config.xml -> FileSystemResource


실습 2

@Slf4j
@Component
public class Runner implements ApplicationRunner {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("applicationContext : {}", applicationContext);

        Resource resource = applicationContext.getResource("classpath:test.txt");//변경
        log.info("resource : {}", resource);
        log.info("exist : {}", resource.exists());
    }
}
//로그 확인
applicationContext : org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4f209819
resource : class path resource [test.txt]
exist : true
  • ApplicationContext의 타입은 실습 1과 동일하게 WebApplicationContext이다.
    하지만 Resource의 구현체는 ClassPathResource이다.
    따라서 ClassPath에 있는 test.txt를 찾을 수 있다.

Comments

Content