2022. 9. 30. 12:56ㆍJAVA/Spring
1. ResourceLoader 인터페이스
ResourceLoader 인터페이스는 Resource 인스턴스를 불러올 수 있는 객체에 의해 구현됩니다. 다음은 ResourceLoader 인터페이스의 정의입니다.
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
모든 ApplicationContext 인터페이스들은 ResourceLoader 인터페이스를 구현하기 때문에 모든 ApplicationContext는 Resource 인스턴스를 얻기 위해 사용할 수 있습니다.
특정 ApplicationContext에서 특정한 접두어를 가지지 않는 위치 경로를 가지고 getResource() 호출할때 ApplicationContext에 따른 적절한 Resource 타입 인스턴스를 받을 것입니다. 예를 들어 ClassPathXmlApplicationContext 인스턴스가 getResource를 호출할때 특정한 접두어를 넣지 않고 경로를 넣으면 기본적으로 ClassPathResource 인스턴스를 반환받을 것입니다.
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
만약 위와 같은 방식으로 ApplicationContext(cxt)가 FileSystemXmlApplicationContext 타입 인스턴스라면 FileSystemResource 인스턴스를 반환받을 것입니다.
만약 ApplicationContext(ctx)가 WebApplicationContext 타입 인스턴스라면 getResource() 호출시 ServletContextResource 인스턴스를 반환받을 것입니다.
정리하면 다음과 같습니다. 접두어를 붙이지 않은상태에서 ApplicationContext 인스턴스가 getResource() 호출시 ApplicationContext 타입에 맞는 Resource 인스턴스가 반환됩니다.
- ClassPathXmlApplicationContext.getResource(location) : ClassPathResource 인스턴스 반환
- FileSystemXmlApplicationContext.getResource(location) : FileSystemResource 인스턴스 반환
- WebApplicationContext.getResource(location) : ServletContextResource 인스턴스 반환
@Component
public class ApplicationContextConfiguration {
@Bean
public ClassPathXmlApplicationContext classPathXmlApplicationContext(){
return new ClassPathXmlApplicationContext();
}
@Bean
public FileSystemXmlApplicationContext fileSystemXmlApplicationContext(){
return new FileSystemXmlApplicationContext();
}
}
Spring IoC 컨테이너에 ClassPathXmlApplicationContext와 FileSystemXmlApplicationContext 빈이 없으므로 따로 설정하여 주입할 수 있도록 합니다.
resources/test.txt 파일을 생성하여 위와 같이 저장합니다.
@SpringBootTest
public class ResourceLoaderApplicationTest {
@Qualifier("webApplicationContext")
@Autowired
private ApplicationContext ctx;
@Autowired
private ClassPathXmlApplicationContext classPathCtx;
@Autowired
private FileSystemXmlApplicationContext fileSystemCtx;
@Autowired
private WebApplicationContext webCtx;
@Test
public void getResource(){
//given
String location = "test.txt";
//when
Resource res1 = ctx.getResource(location);
Resource res2 = classPathCtx.getResource(location);
Resource res3 = fileSystemCtx.getResource(location);
Resource res4 = webCtx.getResource(location);
//then
System.out.println("res1 : " + res1);
System.out.println("res2 : " + res2);
System.out.println("res3 : " + res3);
System.out.println("res4 : " + res4);
}
}
ApplicationContext 인터페이스를 구현하는 ClassPathXmlApplicationContxt, FileSystemXmlApplicationContext, WebApplicationContxt 빈이 3개 존재하므로 의존 객체로 ApplicationContext 의존 객체에 주입하기 위해서는 특정한 빈을 선택해야 합니다. 저 같은 경우 스프링에서 기본적으로 설정한 WebApplicationContxt 빈을 주입하겠습니다.
위 테스트의 결과는 다음과 같습니다.
res1 : ServletContext resource [/test.txt]
res2 : class path resource [test.txt]
res3 : file [C:\Users\qkdlf\Study\Spring\spring_basic\resource_loader\test.txt]
res4 : ServletContext resource [/test.txt]
위 실행 결과를 통해서 location 문자열 변수에 특정한 접두어를 붙이지 않고 각각의 ApplicationContext 인스턴스가 getResource를 호출하면 그에 맞는 Resource 인스턴스타입들을 반환하는 것을 알 수 있습니다.
이번에는 location 변수에 "classpath:" 접두어를 붙인 상태에서 다시 실행해보도록 하겠습니다.
@Test
public void getResource_withPrefix_classpath(){
//given
String location = "classpath:test.txt";
//when
Resource res1 = ctx.getResource(location);
Resource res2 = classPathCtx.getResource(location);
Resource res3 = fileSystemCtx.getResource(location);
Resource res4 = webCtx.getResource(location);
//then
System.out.println("res1 : " + res1);
System.out.println("res2 : " + res2);
System.out.println("res3 : " + res3);
System.out.println("res4 : " + res4);
}
실행결과는 다음과 같습니다.
res1 : class path resource [test.txt]
res2 : class path resource [test.txt]
res3 : class path resource [test.txt]
res4 : class path resource [test.txt]
위 실행결과를 통해 자원 경로에 접두어인 "classpath:"를 붙인 상태에서 각각의 ApplicationContext 인스턴스들이 getResource 메서드를 호출했을때의 결과는 전부 ClassPathResource 타입의 인스턴스를 반환한 것을 알 수 있습니다.
이번에는 접두어에 "file:"과 "https:"를 붙인 상태에서 각각의 ApplicationContext 인스턴스들이 getResource를 호출한 결과를 보도록 하겠습니다.
@Test
public void getResource_withPrefix_file(){
//given
String location = "file:test.txt";
//when
Resource res1 = ctx.getResource(location);
Resource res2 = classPathCtx.getResource(location);
Resource res3 = fileSystemCtx.getResource(location);
Resource res4 = webCtx.getResource(location);
//then
System.out.println("res1 : " + res1);
System.out.println("res2 : " + res2);
System.out.println("res3 : " + res3);
System.out.println("res4 : " + res4);
}
res1 : URL [file:test.txt]
res2 : URL [file:test.txt]
res3 : URL [file:test.txt]
res4 : URL [file:test.txt]
@Test
public void getResource_withPrefix_https(){
//given
String location = "https:test.txt";
//when
Resource res1 = ctx.getResource(location);
Resource res2 = classPathCtx.getResource(location);
Resource res3 = fileSystemCtx.getResource(location);
Resource res4 = webCtx.getResource(location);
//then
System.out.println("res1 : " + res1);
System.out.println("res2 : " + res2);
System.out.println("res3 : " + res3);
System.out.println("res4 : " + res4);
}
res1 : URL [https:test.txt]
res2 : URL [https:test.txt]
res3 : URL [https:test.txt]
res4 : URL [https:test.txt]
위 두결과를 통해서 "file:", "https:" 접두어를 붙인 상태에서 getResource를 호출하면 UrlResource 타입의 인스턴스를 반환받는 것을 알 수 있습니다.
위 내용들을 정리하면 다음과 같습니다.
접두어(Prefix) | 예시 | 설명 |
classpath: | classpath:com/myapp/config.xml | classpath로부터 불러오기 |
file: | file:///data/config.xml | 파일 시스템으로부터 URL로서 불러오기 |
https: | https://myserver/logo.png | URL로서 불러오기 |
없음 | /data/config.xml | ApplicationContext의 타입에 따라 달려있음 |
References
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-resourceloader
source code : https://github.com/yonghwankim-dev/spring_study/blob/master/resource_loader/src/test/java/kr/yh/ResourceLoaderApplicationTest.java
'JAVA > Spring' 카테고리의 다른 글
[Spring] ResourceLoaderAware 인터페이스 (0) | 2022.10.04 |
---|---|
[Spring] ResourcePatternResolver 인터페이스 (0) | 2022.10.03 |
[Spring] Resource 인터페이스와 Resource 인터페이스 구현체 (0) | 2022.09.25 |
[Spring][IoC] ApplicationEventPublisher (0) | 2022.09.23 |
[Springboot] 내장 웹 서버(Embedded Web Servers) #1 (0) | 2022.09.23 |