[Spring] ResourceLoaderAware 인터페이스

2022. 10. 4. 12:52JAVA/Spring

1. ResourceLoaderAware 인터페이스는 무엇인가?

ResourceLoaderAware 인터페이스는 ResourceLoader 참조가 될 컴포넌트를 식별하는 콜백(callback) 인터페이스입니다. 다음은 ResourceLoaderAware 인터페이스의 정의입니다.

public interface ResourceLoaderAware {

    void setResourceLoader(ResourceLoader resourceLoader);
}

한 클래스가 ResourceLoaderAware 인터페이스를 구현하고 ApplicationContext에 배포되면 ApplicationContext에서 ResourceLoaderAware로써 인식됩니다. 그런 다음 ApplicationContext는 setResourceLoader(ResourceLoader)를 호출하여 매개변수에 스스로를 전달합니다. (Srping의 모든 ApplicationContext는 ResourceLoader를 구현합니다.)

 

ApplicationContext는 ResourceLoader이기 때문에 빈(bean)은 ApplicationContextAware 인터페이스를 구현하고 제공된 ApplicationContext를 직접 사용하여 리소스를 불러올수 있습니다. 그러나 일반적으로 필요한 경우에 전문화된 ResourceLoader 인터페이스를 사용하는 것이 좋습니다. 코드는 전체 Spring ApplicationContext 인터페이스가 아닌 Resource를 불러오는 인터페이스(유틸리티 인터페이스로 간주될 수 있음)에만 결합됩니다.

 

Applicationc 컴포넌트에서 ResourceLoaderAware 인터페이스를 구현하는 대신에 ResourceLoader의 자동 주입을 사용할 수도 있습니다. 기존 생성자와 byType 자동주입 모드는 각각 생성자 인수 또는 setter 메서드 매개변수에 대한 ResourceLoader를 제공할 수 있습니다. 필드 자동 주입 기능 및 여러 매개 변수 메서드를 포함하여 유연성을 높이려면 애노테이션 기반 자동 주입 기능을 사용하는 것이 좋습니다. 이 경우에 @Autowired 애노테이션을 생성자, setter, 필드 중 하나에 설정하여 ResourceLoader를 자동 주입합니다.

 

2. ResourceLoaderAware 인터페이스 구현

다음 예제는 ResourceLoaderAware 인터페이스를 구현한 클래스를 빈으로 등록하여 ResourceLoader로 자원을 불러오는 예제입니다.

public class ResourceLoaderAwareImpl implements ResourceLoaderAware {
    private ResourceLoader resourceLoader;

    public ResourceLoader getResourceLoader(){
        return resourceLoader;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public Resource getResource(String path){
        return this.getResourceLoader().getResource(path);
    }

}
@Component
public class ApplicationContextConfiguration {
    @Bean
    public ClassPathXmlApplicationContext classPathXmlApplicationContext(){
        return new ClassPathXmlApplicationContext();
    }

    @Bean
    public ResourceLoaderAwareImpl resourceLoaderAwareImpl(){
        ResourceLoaderAwareImpl resourceLoaderAwareImpl = new ResourceLoaderAwareImpl();
        resourceLoaderAwareImpl.setResourceLoader(new ClassPathXmlApplicationContext());
        return resourceLoaderAwareImpl;
    }
}

 

resources/test.txt

test.txt의 첫번째 줄
test.txt의 두번째 줄
test.txt의 세번째 줄

 

테스트 코드

    @Test
    public void resourceLoaderAwareTest() throws IOException {
        //given
        ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfiguration.class);
        //when
        ResourceLoaderAwareImpl resourceLoaderAware = ctx.getBean(ResourceLoaderAwareImpl.class);
        Resource resource = resourceLoaderAware.getResource("test.txt");
        String content = Files.readString(Path.of(resource.getURI()));
        //then
        System.out.println(content);

    }

 

실행결과

test.txt의 첫번째 줄
test.txt의 두번째 줄
test.txt의 세번째 줄

 

3. ResourceLoaderAware 인터페이스를 구현하지 않고 자동주입을 하는 방법

이 예제는 ResourceLoaderAware 인터페이스를 구현하지 않고 자동주입(@Autowired)를 이용하여 ResourceLoader를 주입받고 빈으로 등록하여 자원을 불러오는 예제입니다.

@Service
public class ResourceLoaderService {
    private final ResourceLoader resourceLoader;

    @Autowired
    public ResourceLoaderService(@Qualifier("classPathXmlApplicationContext") ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public ResourceLoader getResourceLoader(){
        return resourceLoader;
    }

    public Resource getResource(String path){
        return this.getResourceLoader().getResource(path);
    }
}

 

설정파일에서 빈 등록

@Component
public class ApplicationContextConfiguration {
    @Bean
    public ClassPathXmlApplicationContext classPathXmlApplicationContext(){
        return new ClassPathXmlApplicationContext();
    }

    @Bean
    public ResourceLoaderService resourceLoaderAwareImpl2(){
        return new ResourceLoaderService(new ClassPathXmlApplicationContext());
    }
}

 

테스트코드

    @Test
    public void resourceLoaderAware_Without_Test() throws IOException {
        //given
        ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationContextConfiguration.class);
        //when
        ResourceLoaderService resourceLoaderAware = ctx.getBean(ResourceLoaderService.class);
        Resource resource = resourceLoaderAware.getResource("test.txt");
        String content = Files.readString(Path.of(resource.getURI()));
        //then
        System.out.println(content);
    }

 

실행결과

test.txt의 첫번째 줄
test.txt의 두번째 줄
test.txt의 세번째 줄

 

References

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-resourceloaderaware
source code : https://github.com/yonghwankim-dev/spring_study/blob/master/resource_loader/src/test/java/kr/yh/ResourceLoaderApplicationTest.java