2. 使用 Resource

在 Spring 中,我们可以通过 Resource 接口来定位并读取资源文件。Spring 提供了资源加载机制,通过 ResourceLoader 来决定使用哪种 Resource 实现类,具体取决于我们提供的路径。

Resource 接口本身并不直接代表资源内容,而是访问资源内容的一种方式。我们可以通过多种方式获取 Resource 实例。

2.1. 使用 ResourceLoader

如果我们希望延迟加载资源,可以使用 ResourceLoader

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

我们也可以通过 @Autowired 注入 ResourceLoader

@Autowired
private ResourceLoader resourceLoader;

2.2. 使用 @Value

更简洁的方式是直接通过 @Value 注解注入 Resource

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

3. 将 Resource 转换为 String

获取到 Resource 后,我们需要将其内容读取为字符串。我们可以创建一个 ResourceReader 工具类,提供静态方法 asString 来完成这个任务。

首先,获取输入流:

InputStream inputStream = resource.getInputStream();

接着,使用 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);
        }
    }

    // 其他工具方法
}

除了 FileCopyUtils,我们也可以使用 StreamUtils.copyToString 等方式完成转换。

我们还可以再提供一个方法 readFileToString,用于根据路径加载资源并转换为字符串:

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

4. 添加 @Configuration

如果每个 Bean 都单独加载资源内容,不仅会造成代码重复,还可能占用更多内存。一个更优雅的做法是,在应用上下文初始化时统一加载资源内容,并通过 Spring Bean 管理其生命周期。

我们可以创建一个配置类:

@Configuration
public class LoadResourceConfig {

    // Bean 定义
}

4.1. 使用 Bean 保存资源内容

在配置类中定义 Bean,用于保存资源内容:

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

然后在需要使用的类中通过 @Autowire 注入:

public class LoadResourceAsStringIntegrationTest {
    private static final String EXPECTED_RESOURCE_VALUE = "...";  // 文件内容

    @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 (SpEL) 来实现资源内容的直接注入。

使用 @Value 注解将资源内容注入到字段中:

public class LoadResourceAsStringIntegrationTest {
    private static final String EXPECTED_RESOURCE_VALUE = "...";  // 文件内容

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

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

我们在 ResourceReader 中添加了一个辅助方法,使用 Apache Commons 的 FileUtils 来读取资源:

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

✅优点:SpEL 写法紧凑,适合简单场景。
❌缺点:表达式过长或复杂时,可读性下降,建议封装成工具方法。

6. 总结

本篇文章我们介绍了几种在 Spring 中将资源文件内容加载为字符串的方式:

  • ✅ 通过 ResourceLoader@Value 获取 Resource 实例
  • ✅ 使用 FileCopyUtilsStreamUtilsResource 转换为 String
  • ✅ 通过 @Configuration 集中管理资源加载逻辑,避免重复代码
  • ✅ 使用 SpEL 直接注入资源内容,适用于简单场景

这些方法各有优劣,根据项目复杂度和需求选择合适的方式即可。对于资源内容复用较多的场景,推荐使用配置类 + Bean 注入的方式,结构清晰、易于维护。

完整示例代码已托管在 GitHub:Load Resource as String 示例代码


原始标题:Load a Resource as a String in Spring | Baeldung