ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [10] 추상화 - Resource 추상화
    Spring/Spring 핵심 기술 2020. 4. 21. 09:51
    반응형

    SpringFramework에서는 java.net.URL interface를 org.springframework.core.io.Resource interface type으로 상속 받아 추상화합니다. java.net.URL에는 resource 접근과 관리에 대한 기능이 부족하여 org.springframework.core.io.Resource로의 추상화를 통해 필요한 기능들을 지원하고 있습니다. 다음은 부족한 기능들의 예입니다.

    1. class path 기준으로 resource 읽어오는 기능이 필요하지만 java.net.URL에서는 필요로 하는 기능을 제공하지 않습니다.
    2. java.net.URL에는 ServletContext 기준으로 상대 경로를 읽어오는 기능이 없습니다.
    3. 새로운 핸들러를 등록하여 특별한 URL 접두사를 만들어 사용은 가능하나 구현이 복잡하고 이를 편리하게 처리할 있는 method 부족합니다.

    (java.net.URL class World Wide Web상의 Resource 가르키는 Uniform Resource Locator 표현합니다.)

     

     

    우리는 ApplicationContext를 생성할 때부터 이미 resource를 사용했습니다. XML file로 ApplicationContext를 생성할 때 class path와 file system 두 가지 기준으로 resource에 접근할 수 있습니다. 

    ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
    ApplicationContext ctx = new FileSystemXmlApplicationContext("context.xml");

    ClassPathXmlApplicationContext()과 FileSystemXmlApplicationContext()에 매개 값으로 전달된 xml file을 가리키는 문자열은 resource를 가르킵니다. 즉, content.xml이라는 resource를 찾아서 bean 설정 file로 사용하게 됩니다. 위의 두 가지 ApplicationContext 생성 구문은 "context.xml"이라는 resource를 각각 classpath resource와 filesystem resource로써 resolving 하게 됩니다.

     

     

     

    [Resource 주요 method]

    1. getInputStream()
    2. exist() : Resource 존재할 수도 있고 아닐 수도 있다고 가정하기 때문에 Resource의 존재여부를 확인하는 메서드를 제공합니다.
    3. isOpen()
    4. getDescription()
    5. getFile() : Resource file 가져옵니다. 다만 모든 Resource 항상 file 가져올 있는 것은 아닙니다.

     

     

    [Resource 구현체]

    1. UrlResource : java.net.URL참고. "http", "https", "ftp", "file", "jar" 등의 접두어를 지원합니다.
    2. ClassPathResource : "classpath"라는 접두어 붙여 표현한 resource이며 접두어에 붙은 resource는 class path resource 됩니다.
    3. FileSystemResource
    4. ServletContextResource : 어플리케이션 루트로 부터 상대경로를 사용하여 resource 찾습니다.(읽어들이는 type Application Context 관련이 있기 때문에 가장 많이 사용되는 resource입니다..)

     

     

    [Resource 읽어오기]

    1. 생성되는 ApplicationContext 종류 따라 이후 사용되는 resource type이 결정됩니다.

    • ClassPathXmlApplicationContext -> Context root 이하의 모든 resource를 ClassPathResource로 간주합니다.
    • FileSystemXmlApplicationContext -> Context root 이하의 모든 resource를 FileSystemResource로 간주합니다.
    • WebApplicationContext -> Context root 이하의 모든 resource를  ServletContextResource로 간주합니다.

     

    2. ApplicationContext 종류에 상관 상관없이 resource를 원하는 resource type으로 지정하고자 한다면 resource path 매개변수로 전달할 java.net.URL 정의된 "classpath:" 같은 접두어를 붙인 location 문자열을 사용하면 됩니다. 일반적으로 WebApplitcationContext를 사용하므로 접두어 없이 ClassPathResource를 사용하고자 하면 ServletContextResource로 간주되어 되어 원하지 않는 결과를 보여줄 있으니 ClassPathResource 사용하는 경우는 반드시 "classpath:"접두어를 붙여야 합니다.

    • classpath:test.txt -> ClassPathResource
    • file:///test/path/test.txt -> FileSystemResource

    WebServerApplicationContext로 ApplicationContext를 생성하고 동일한 resource에 대해 classpath 접두어를 붙였을 때와 붙이지 않았을 때의 resource type(resource object의 class)을 확인해보도록 합시다. AppRunner.java를 다음과 같이 수정 후 실행해주세요.

    @Component
    public class AppRunner implements ApplicationRunner {
    
        @Autowired
        ApplicationContext resourceLoader; //	①
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
    
            System.out.println(resourceLoader.getClass());
    
            Resource resource1 =  resourceLoader.getResource("classpath:test.txt");	//	②
            System.out.println(resource1.getClass());
    
            Resource resource2 =  resourceLoader.getResource("test.txt");	//	③
            System.out.println(resource2.getClass());
        }
    }

    ① WebApplicationContext를 주입받습니다. Context root부터 모든 resource는 ServletContextResource로 간주됩니다.

    resource를 가져올 때 접두어 "classpath:"를 붙여서  ClassPathResource임을 명시하여 가져옵니다.

    ③ 접두어 없이 resource를 가져옵니다.

     

    실행결과를 보면 현재 Context는 AnnotationConfigServletWebServerApplicationContext 즉 WebApplicationContext임을 알 수 있습니다. 그러므로 Context root 이하의 모든 resource는 ServletContextResource가 됩니다.

    하지만 resouce에 "classpaath:" prefix를 붙인 경우는 ClassPathResource로 resource를 가져오는 것을 확인할 수 있습니다.

    Prefix에 따른 resource type 변화

     

    댓글

Designed by Tistory.