Springでリソースを文字列としてロードする
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メソッドを呼び出して
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のにあります。