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 |