Springでリソースを文字列としてロードする

1. 概要

このチュートリアルでは、文字列としてテキストを含むリソースのコンテンツをSpring Beanに挿入するさまざまな方法を見ていきます*。
リソースの検索とその内容の読み取りについて見ていきます。
また、ロードされたリソースを複数のBean間で共有する方法を示します。 link:/spring-annotations-resource-inject-autowire [依存性注入に関連する注釈]を使用してこれを示しますが、https:// wwwを使用しても同じことが実現できます。 .baeldung.com / spring-xml-injection [XML-based injection]およびXMLプロパティファイルでBeanを宣言します。

2. _Resource_の使用

link:/spring-classpath-file-access[_Resource_]インターフェイスを使用して、リソースファイルの検索を簡素化できます。 Springは、リソースローダーを使用してリソースを見つけて読み取るのに役立ちます。リソースローダーは、提供されるパスに応じて、どの_Resource_実装を選択するかを決定します。 _Resource_は、コンテンツ自体ではなく、リソースのコンテンツにアクセスする方法です。
link:/spring-classpath-file-access [クラスパス上のリソースの_Resource_インスタンスを取得]へのいくつかの方法を見てみましょう。

2.1. _ResourceLoader_の使用

遅延読み込みを使用する場合は、_ResourceLoader_クラスを使用できます。
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:resource.txt");
_ @ Autowired_を使用して、_ResourceLoader_をBeanに挿入することもできます。
@Autowired
private ResourceLoader resourceLoader;

2.2 _ @ Resource_の使用

Resource_ @ Value_を使用して、_Resource_をSpring Beanに直接注入できます。
@Value("classpath:resource.txt")
private Resource resource;

3. _Resource_から_String_への変換

_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
}
たとえば、https://www.baeldung.com/convert-input-stream-to-string [これを実現する他の多くの方法があります]、たとえば、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);
}

[[adding-configuration=class]]
=== 4. _Configuration_クラスの追加

各Beanがリソース__String__sを個別に挿入する必要がある場合、コードの重複と、_String_の独自のコピーを持つBeanによるメモリの使用の両方が発生する可能性があります。
アプリケーションコンテキストの読み込み時に1つまたは複数のSpring Beanにリソースのコンテンツを注入することにより、よりきれいなソリューションを実現できます。 このようにして、このコンテンツを使用する必要のあるさまざまなBeanからリソースを読み取るための実装の詳細を隠すことができます。
@Configuration
public class LoadResourceConfig {

    // Bean Declarations
}

4.1. リソース文字列を保持するBeanの使用

_ @ Configuration_クラスのリソースコンテンツを保持するBeanを宣言しましょう。
@Bean
public String resourceString() {
    return ResourceReader.readFileToString("resource.txt");
}
link:/spring-autowire[[email protected]_]注釈を追加して、登録済みのBeanをフィールドに注入しましょう。
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_アノテーションとBeanの名前を使用します*-_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);
    }
}
ここでは、_Resources#readFileToString_を呼び出して、_ @ Value_アノテーション内の__“ classpath:” –__ prefixedパスを使用して、ファイルの場所を記述しています。
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._への読み取り方法を見ました。
次に、リソースのロードの実装を非表示にする方法と、修飾されたBeanを_ @ Configuration_に作成して文字列を自動配線できるようにすることで、文字列の内容をBean間で共有する方法も示しました。
最後に、コンパクトで即時のソリューションを提供するSpELを使用しましたが、複雑になるのを防ぐにはカスタムヘルパー関数が必要でした。
いつものように、例のコードはhttps://github.com/eugenp/tutorials/tree/master/spring-static-resources[GitHubで]にあります。