본문 바로가기

STUDY/스프링 철저 입문

1-8) 스프링 리소스(Resource): Resource, ResourceLoader

 - 스프링 리소스: Resource 추상 클래스

 

서비스를 개발하다 보면 리소스 파일에 접근할 일이 종종 있다. 설정 정보를 불러오기위해 resources 폴더의 .properties 파일에 접근하기도 하고, 외부 사이트의 이미지 파일을 불러오기도 한다. 스프링에는 리소스에 접근하기 위한 추상클래스 Resource가 존재하고, 각 상황별로 쓸 수 있는 구현 클래스가 존재한다.

 

Resource의 구현 클래스들

 

 

 

 - 스프링 리소스 편하게 가져오기: ResourceLoader

 

개발자 입장에서는 상황에 맞는 Resource 구현 클래스를 사용해야 한다는 것 자체가 부담으로 다가올 수 도 있다. 그래서 스프링에서는 ResourceLoader가 존재한다. ResourceLoader는 리소스의 경로를 보고 적절한 Resource 구현 클래스를 사용하고, 개발자에게 이를 반환해준다. 

 

package resource;

...

@Configuration
@ComponentScan(basePackages = {"resource"})
public class AppContextConfig {
	...
}

 

package resource;

...

@Service
public class MyResource {
  @Autowired
  private ResourceLoader resourceLoader;

  public Resource getResource(String location) {
    return resourceLoader.getResource(location);
  }
  ...
}

 

package resource;

...

public static void main(String[] args) {
  AnnotationConfigApplicationContext appContext =
  new AnnotationConfigApplicationContext(AppContextConfig.class);
  MyResource myResource = appContext.getBean(MyResource.class);

  Resource resource1 = myResource.getResource("classpath:property.properties");
  System.out.println(resource1.getClass());

  Resource resource2 = myResource.getResource("http://www.resource.com");
  System.out.println(resource2.getClass());
}

...

 

AppplicationContext를 만들고, ResourceLoader를 사용하여 Resource를 반환하는 MyResource 클래스를 만들었다. 그리고 main에서 이를 MyResource를 사용하여 "classclasspath:property.properties", "http://www.resource.com"를 경로로 하는 리소스를 반환하고 클래스 타입을 출력한다.

 

class org.springframework.core.io.ClassPathResource
class org.springframework.core.io.UrlResource

 

실행 결과 다음과 같이, 클래스 패스에 접근하는 경우 ClassPathResource를 반환해주고, URL에 접근하는 경우 URLResource를 반환하여 준다.

 

 

 - 실습 1: 리소스 파일 읽기

 

이제 한번 resources 폴더에 resource.txt 파일을 만들고 불러오는 실습을 해보겠다. resource 폴더를 클래스 패스에 속하므로 resourceLoader를 사용하여, 다음과 같이 "classpath:resource.txt" 경로의 Resource를 불러오면 된다.

 

// resources 폴더의 resource.txt
Hello World

 

...
public static void main(String[] args) throws IOException {
  AnnotationConfigApplicationContext appContext =
  new AnnotationConfigApplicationContext(AppContextConfig.class);
  MyResource myResource = appContext.getBean(MyResource.class);

  Resource resource = myResource.getResource("classpath:resource.txt");
  InputStream inStream = resource.getInputStream();
  String content = StreamUtils.copyToString(inStream, StandardCharsets.UTF_8);
  System.out.println(content);
  inStream.close();
}
...

 

 

 - 실습 2: 리소스 파일 쓰기

 

리소스 파일을 쓰기 위해서 WritableResource라는 추상 클래스가 존재하지만, ClassPathResource는 WritableResource를 구현하고 있지 않다. 그래서 File 객체를 가져와서 파일 쓰기를 하였다.

 

...
public static void main(String[] args) throws IOException {
  AnnotationConfigApplicationContext appContext =
  new AnnotationConfigApplicationContext(AppContextConfig.class);
  MyResource myResource = appContext.getBean(MyResource.class);

  Resource resource = myResource.getResource("classpath:resource.txt");
  InputStream inStream = resource.getInputStream();
  String content = StreamUtils.copyToString(inStream, StandardCharsets.UTF_8);
  System.out.println("content: " + content);
  inStream.close();

  File file = resource.getFile();
  OutputStream outStream = new FileOutputStream(file);
  StreamUtils.copy("Goodbye World".getBytes(), outStream);
  outStream.close();

  inStream = resource.getInputStream();
  String newContent = StreamUtils.copyToString(inStream, StandardCharsets.UTF_8);
  System.out.println("newContent:" + newContent);
  inStream.close();
}
...

 

content: Hello World
newContent:Goodbye World

 

실행 결과를 보면, resource.txt가 "Hello World"에서 "Goodbye World"로 바뀐 것을 볼 수 있다.

 

 

 - 정리

 

리소스 접근을 위한 Resource 추상클래스와, 각각 상황에 맞는 Resource 구현클래스들이 있다. 그리고 Resource 구현클래스들을 보다 편하게 사용하기 위한 ResourceLoader도 존재 한다. 이렇게 개발자의 수고를 덜어주는 유익한 도구들을 보면, 스프링에 대한 고마움이 저절로 강해진다. 

728x90