1. 概要

このチュートリアルでは、テキストを文字列として含むリソースのコンテンツを SpringBeansに注入するさまざまな方法を見ていきます。

リソースの検索とその内容の読み取りについて見ていきます。

また、ロードされたリソースを複数のBean間で共有する方法についても説明します。 これは、依存性注入に関連するアノテーションを使用して示しますが、 XMLベースの注入を使用し、XMLプロパティファイルでBeanを宣言することでも同じことができます。

2. リソースの使用

Resource インターフェースを使用すると、リソースファイルの検索を簡単に行うことができます。 Springは、リソースローダーを使用してリソースを見つけて読み取るのに役立ちます。リソースローダーは、提供されたパスに応じて、選択するResource実装を決定します。 Resource は、コンテンツ自体ではなく、リソースのコンテンツに効果的にアクセスする方法です。

クラスパス上のリソースのリソースインスタンスを取得するいくつかの方法を見てみましょう。

2.1. ResourceLoaderを使用する

遅延読み込みを使用する場合は、クラスResourceLoaderを使用できます。

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

ResourceLoader@Autowiredを使用してBeanに注入することもできます。

@Autowired
private ResourceLoader resourceLoader;

2.2. @Resourceを使用する

Resource@Valueを使用してSpringBeanに直接注入できます。

@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[に変換してみましょう。 X189X]。

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

4. 構成クラスの追加

各BeanがリソースStringを個別に注入する必要がある場合、Stringの独自のコピーを持つBeanによるコードの重複とメモリの使用の増加の両方の可能性があります。

アプリケーションコンテキストのロード時にリソースのコンテンツを1つまたは複数のSpringBeanに注入することで、より優れたソリューションを実現できます。 このようにして、このコンテンツを使用する必要のあるさまざまなBeanからリソースを読み取るための実装の詳細を非表示にすることができます。

@Configuration
public class LoadResourceConfig {

    // Bean Declarations
}

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

@Configurationクラスにリソースコンテンツを保持するBeanを宣言しましょう。

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

@Autowired アノテーションを追加して、登録済みの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);
    }
}

ここでは、[X15X] @Value アノテーション内の「classpath:」– プレフィックスパスを使用して、ファイルの場所を説明する ResourceReader#readFileToStringを呼び出しました。

SpELのコード量を減らすために、クラス ResourceReader にヘルパーメソッドを作成しました。このメソッドは、Apache Commons FileUtilsを使用して指定されたパスからファイルにアクセスします。

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

6. 結論

このチュートリアルでは、リソースを文字列変換するいくつかの方法を確認しました。

まず、ファイルにアクセスするための Resource を作成する方法と、ResourceからString。への読み取り方法を確認しました。

次に、リソースローディングの実装を非表示にし、 @Configuration で修飾されたBeanを作成して文字列の内容をBean間で共有できるようにし、文字列を自動配線できるようにする方法も示しました。

最後に、コンパクトで即時のソリューションを提供するSpELを使用しましたが、複雑になりすぎないようにカスタムヘルパー関数が必要でした。

いつものように、例のコードはGitHubにあります。