1. 개요

이 예제에서는 문자열로 텍스트를 포함하는 리소스의 내용을 Spring 빈에 주입하는 다양한 방법을 살펴볼 것 입니다.

리소스를 찾고 콘텐츠를 읽는 방법을 살펴보겠습니다.

또한 여러 빈에서 로드된 리소스를 공유하는 방법을 보여줍니다. XML 기반 주입 을 사용 하고 XML 속성 파일에서 빈을 선언 하여 동일한 결과를 얻을 수도 있지만 의존성 주입과 관련된 어노테이션을 사용하여 이를 보여줍니다 .

2. 리소스 사용

Resource 인터페이스 를 사용하여 리소스 파일 찾기를 단순화할 수 있습니다 . Spring은 제공된 경로에 따라 선택할 리소스 구현을 결정하는 리소스 로더를 사용하여 리소스를 찾고 읽을 수 있도록 도와줍니다 . 리소스 는 콘텐츠 자체가 아니라 리소스의 콘텐츠에 효과적으로 액세스하는 방법입니다

classpath의 리소스에 대한 Resource 인스턴스 를 획득하는 몇 가지 방법을 살펴보겠습니다 .

2.1. 리소스 로더 사용

지연 로딩을 선호한다면 ResourceLoader 클래스를 사용할 수 있습니다 .

ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:resource.txt");

@Autowired 를 사용하여 ResourceLoader 를 빈에 주입할 수도 있습니다 .

@Autowired
private ResourceLoader resourceLoader;

2.2. @Value 사용

@Value 를 사용하여 리소스 를 Spring 빈에 직접  주입할 수 있습니다 .

@Value("classpath:resource.txt")
private Resource resource;

3. 리소스 에서 문자열 로 변환

Resource 에 접근할 수 있게 되면 그것을 String 으로 읽을 수 있어야 합니다 . 이 작업을 수행하기 위해 정적 메서드 asString 을 사용하여 ResourceReader 유틸리티 클래스를 만들어 보겠습니다 .

먼저 InputStream 을 획득해야 합니다 .

InputStream inputStream = resource.getInputStream();

다음 단계는 이 InputStream 을 가져와 String 으로 변환하는 것 입니다. Spring 고유의 FileCopyUtils#copyToString 메소드를 사용할 수 있습니다.

public class ResourceReader {

    public static String asString(Resource resource) {
        try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
            return FileCopyUtils.copyToString(reader);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    // more utility methods
}

예를 들어 Spring의 StreamUtils 클래스 의 copyToString 을 사용하여 이를 달성하는 다른 많은 방법이 있습니다 .

또한 경로에 대한 Resource 를 검색하는 또 다른 유틸리티 메서드 인 readFileToString 을 만들고 asString 메서드를 호출하여 이를 String 으로 변환해 보겠습니다 .

public static String readFileToString(String path) {
    ResourceLoader resourceLoader = new DefaultResourceLoader();
    Resource resource = resourceLoader.getResource(path);
    return asString(resource);
}

4. 구성 클래스 추가

각 빈이 리소스 String 을 개별적으로 주입해야 하는 경우, String 의 개별 복사본을 가진 빈이 코드를 복제하고 메모리를 더 많이 사용할 가능성이 있습니다 .

애플리케이션 컨텍스트를 로드할 때 리소스의 내용을 하나 이상의 Spring 빈에 주입하여 보다 깔끔한 솔루션을 얻을 수 있습니다. 이러한 방식으로 이 콘텐츠를 사용해야 하는 다양한 빈에서 리소스를 읽기 위한 구현 세부 정보를 숨길 수 있습니다.

@Configuration
public class LoadResourceConfig {

    // Bean Declarations
}

4.1. 리소스 문자열을 보유하는 Bean 사용

@Configuration 클래스 에 리소스 내용을 담기 위해 빈을 선언합시다 :

@Bean
public String resourceString() {
    return ResourceReader.readFileToString("resource.txt");
}

이제 @Autowired 어노테이션 을 추가하여 등록된 빈을 필드에 주입해 보겠습니다 .

public class LoadResourceAsStringIntegrationTest {
    private static final String EXPECTED_RESOURCE_VALUE = "...";  // The string value of the file content

    @Autowired
    @Qualifier("resourceString")
    private String resourceString;

    @Test
    public void givenUsingResourceStringBean_whenConvertingAResourceToAString_thenCorrect() {
        assertEquals(EXPECTED_RESOURCE_VALUE, resourceString);
    }
}

이 경우에는 @Qualifier 어노테이션과 빈의 이름을 사용합니다. 같은 유형의 여러 필드를 삽입해야 할 수도 있기 때문입니다String .

한정자에 사용된 Bean 이름은 구성 클래스에서 Bean을 생성하는 메소드의 이름에서 파생된다는 점에 유의해야 합니다.

5. SpEL 사용

마지막으로 리소스 파일을 클래스의 필드에 직접 로드하는 데 필요한 코드를 설명하기 위해 Spring Expression Language를 사용하는 방법을 살펴보겠습니다.

@Value 어노테이션을 사용하여 파일 내용을 resourceStringUsingSpel 필드에 삽입해 보겠습니다 .

public class LoadResourceAsStringIntegrationTest {
    private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content

    @Value(
      "#{T(com.baeldung.loadresourceasstring.ResourceReader).readFileToString('classpath:resource.txt')}"
    )
    private String resourceStringUsingSpel;

    @Test
    public void givenUsingSpel_whenConvertingAResourceToAString_thenCorrect() {
        assertEquals(EXPECTED_RESOURCE_VALUE, resourceStringUsingSpel);
    }
}

여기 에서 "classpath:" 를 사용하여 파일의 위치를 ​​설명하는 ResourceReader#readFileToString 을 호출했습니다. @Value 어노테이션 내부에 접두사가 붙은 경로 입니다.

SpEL의 코드 양을 줄이기 위해  Apache Commons FileUtils 를 사용하여 제공된 경로에서 파일에 액세스하는 ResourceReader 클래스의 도우미 메서드를 만들었습니다.

public class ResourceReader {
    public static String readFileToString(String path) throws IOException {
        return FileUtils.readFileToString(ResourceUtils.getFile(path), StandardCharsets.UTF_8);
    }
}

6. 결론

이 사용방법(예제)에서는 리소스를 String 으로 변환하는 몇 가지 방법을 검토했습니다 .

먼저 파일에 접근하기 위한 Resource 를 생성하는 방법과 Resource 에서 String 으로 읽는 방법을 알아보았습니다 .

다음으로 리소스 로딩 구현을 숨기고 문자열이 자동 연결되도록 하는 @Configuration 에 정규화된 빈을 생성하여 빈 간에 문자열 내용을 공유하는 방법도 보여주었습니다 .

마지막으로 우리는 컴팩트하고 즉각적인 솔루션을 제공하는 SpEL을 사용했지만 너무 복잡해지지 않도록 사용자 지정 도우미 기능이 필요했습니다.

항상 그렇듯이 예제 코드는 GitHub 에서 찾을 수 있습니다.

Generic footer banner