Spring/스프링 프레임워크 핵심 원리

[Spring] #13. Resource 추상화

sujin7837 2020. 12. 24. 20:15
반응형

Resouce 추상화

-java.net.URL이라는 클래스를 org.springframework.core.io.Resource라는 클래스로 감싸서 low level에 있는 resource에 접근하는 기능입니다.

-클래스 패스를 기준으로 리소스를 읽어오는 기능이 이전에 없었기 때문에 resource를 추상화한 것입니다.

 

//클래스 패스를 기준으로 location에 있는 설정 파일을 찾는 방법

@Autowired
ResourceLoader resourceLoader;

@Override
public void run(ApplicationArguments args) throws Exception {
    var ctx=new ClassPathXmlApplicationContext(configLocation: "sldiflsd.xml");

    Resource resource=resourceLoader.getResource(location: "classpath:text.txt");
    System.out.println(resource.exists());
    System.out.println(resource.getDescription());
    System.out.println(Files.readString(Path.of(resource.getURI())));
}

"sldiflsd.xml"라는 파일의 문자열이 내부적으로 resource로 변환이 됩니다. 그래서 자동으로 getResource의 location에 해당하는 곳으로 갑니다.

 

//파일 시스템 경로 기준으로 location에 있는 설정 파일을 찾는 방법

@Autowired
ResourceLoader resourceLoader;

@Override
public void run(ApplicationArguments args) throws Exception {
    var ctx=new FileSystemXmlApplicationContext(configLocation: "xxx.xml");

    Resource resource=resourceLoader.getResource(location: "classpath:text.txt");
    System.out.println(resource.exists());
    System.out.println(resource.getDescription());
    System.out.println(Files.readString(Path.of(resource.getURI())));
}

-구현체

·UrlResource: java.net.URL 참고, 기본으로 지원하는 프로토콜 http, https, ftp, file, jar

·ClassPathResource: 지원하는 접두어 'classpath:'

·FileSystemResource

·ServletContextResource: 사실상 가장 많이 사용하게 되는 리소스로 웹 애플리케이션 루트에서 상대 경로를 이용하여 리소스를 찾음

-리소스 타입은 location 문자열과 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

코드만으로는 리소스가 어디에서 오는건지 알기 어렵습니다. 그런데 '접두어'가 있으면 경로를 알기 쉽기 때문에 사용을 권장합니다.

@Autowired
ApplicationContext resourceLoader;
//ResourceLoader는 사실상 ApplicationContext이므로 ApplicationContext로 받아옵니다.

@Override
public void run(ApplicationArguments args) throws Exception {
    System.out.println(resourceLoader.getClass());
    //WebApplicationContext 중 하나여야 함
    
    Resource resource=resourceLoader.getResource(location: "classpath:text.txt");
    System.outprintln(resource.getClass());
    //WebApplicationContext->ServletContextResource이므로 원래는 ServletContextResource가 
    출력되어야 하지만, classpath location을 사용했으므로 classpath 리소스가 출력됨

    System.out.println(resource.exists());
    System.out.println(resource.getDescription());
    System.out.println(Files.readString(Path.of(resource.getURI())));
}
@Autowired
ApplicationContext resourceLoader;
//ResourceLoader는 사실상 ApplicationContext이므로 ApplicationContext로 받아옵니다.

@Override
public void run(ApplicationArguments args) throws Exception {
    System.out.println(resourceLoader.getClass());
    //WebApplicationContext 중 하나여야 함

    Resource resource=resourceLoader.getResource(location: "text.txt");
    System.outprintln(resource.getClass());
    //location에서 접두어 'classpath:'를 삭제했으므로 ServletContextResource가 출력됨

    System.out.println(resource.exists());
    System.out.println(resource.getDescription());
    System.out.println(Files.readString(Path.of(resource.getURI())));
}
반응형