본문 바로가기

개발/Spring

Resource 추상화

반응형

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

java.net.URL을 왜 추상화 했을까??
  - java.net.URL 는 classpath 기준으로 가져오는 것이 없었다.
  - ServletContext를 기준으로 상대 경로를 읽어오는 기능이 부족
  - 새로운 핸들러를 등록하여 URL 접미사를 만들어 사용할 수는 있지만 구현이 복잡하고 편의성 메소드가 부족하다!
이러한 이유로 Resource를 만들었다. 

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

var ctx = new ClassPathXmlApplicationContext("sss.xml"); >> 클래스패스 기준으로 리소스 찾음
= new FileSystemXmlApplicationContext("xxx.xml"); >> 파일시스템 기준으로 리소스를 찾음
 >> 내부적으로 리소스로 변환이 된다. 

리소스 읽어오기
 - Resource 의 타입은 location 문자열과 ApplicationContext의 타입에 따라 결정 된다.
 읽어들이는 리소스타입이 ApplicationContext 의 타입에 따라 결정 
  ApplicationContext가 FileSystemXmlApplicationContext면 FileSystemResource 로 된다.
  ApplicationContext가 ClassPathXmlApplicationContext면 ClassPathResource 로 된다. 
  ApplicationContext가 WebApplicationContext면 ServletContextResource 로 된다. 
- ApplicationContext 의 타입에 상관없이 리소스를 강제하려면 java.net.URL 접두어중 하나를 사용할 수 있다.
  classPath:me/config.xml > ClassPathResource
   file:///some/config.xml  > FileSystemResource
  >>  이방식을 추천 ! 접두어를 써 명시적으로 어디서 오는지 알 수 있다.

1. 사용하는 리소스 타입 확인 
 1) getResource() 에 classPath 프리픽스 사용

package com.bpkim.demospring51;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

@Component
public class AppResourceRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext 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());

    }
}

- 실행 결과 
WebServerApplicationContext 이지만 getResource()의 프리픽스가 classpath이므로 ClassPathResrouce 를 사용

*** AnnotationConfigServletWebServerApplicationContext가 WebServerApplicationContext 인 이유


2) 프리픽스 미사용

package com.bpkim.demospring51;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

@Component
public class AppResourceRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext resourceLoader;

    @Override
    public void run(ApplicationArguments args) throws Exception{

        // 어느 리소스를 사용했는지 확인
        System.out.println(resourceLoader.getClass());

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

        // 어느 리소스를 사용했는지 확인
        System.out.println(resource.getClass());

    }
}

- 실행 결과 
 

리소스 이름만 적으면 기본인 ServletContextResource를 이용한다.

 

반응형

'개발 > Spring' 카테고리의 다른 글

데이터 바인딩 추상화: PropertyEditor  (0) 2021.04.22
Validation 추상화  (0) 2021.04.22
Ioc 컨테이너 - ResourceLoader  (0) 2021.04.22
IoC - ApplicationEventPublisher  (0) 2021.04.11
IoC - MessageSource  (0) 2021.04.11