一、概述
在本文中,将研究
将包含文本的资源内容作为 String 注入 Spring beans 的
各种方法。
关注的重点在如何定位资源并读取其内容。
此外,将演示如何在多个 bean 之间共享加载的资源。通过使用与
依赖注入相关的注解
来展示这一点,尽管同样可以通过使用基于
XML 的注入
并在 XML 属性文件中声明 bean 来实现。
2. 使用资源
可以通过使用
Resource
接口来简化查找资源文件的过程。Spring 帮助我们使用资源加载器查找和读取资源,它根据提供的路径决定选择哪个
Resource
实现。
Resource
实际上是一种访问资源内容的方式,而不是内容本身。
让我们看看
获取类路径上资源的
Resource
实例
的一些方法。
2.1。使用资源加载器
如果喜欢使用延迟加载,可以使用类
ResourceLoader :
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:resource.txt");
可以使用
@Autowired
将
ResourceLoader
注入到 bean 中:**
@Autowired
private ResourceLoader resourceLoader;复制
2.2. 使用
@Value
可以使用
@Value
将
Resource
直接注入到 Spring bean 中 :
@Value("classpath:resource.txt")
private Resource resource;复制
3. 从
资源
转换为
字符串
如果需要访问
资源
,就需要能够将其读入并转化为
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
我们还创建另一个实用方法
readFileToString,
它将加载对应路径的
Resource
,并调用
asString
方法将其转换为
String
。
public static String readFileToString(String path) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource(path);
return asString(resource);
}
4.添加 配置类
如果每个 bean 都必须单独注入资源
String
,那么有可能会导致 重复代码和每个 bean 拥有自己的
String
副本而使用更多内存。
可以通过在加载应用程序上下文时将资源的内容注入一个或多个 Spring bean 来实现更简洁的解决方案。通过这种方式,可以隐藏从需要使用此内容的各种 bean 中读取资源的实现细节。
@Configuration
public class LoadResourceConfig {
// Bean Declarations
}
4.1。使用持有资源字符串的 Bean
声明 bean 以在
@Configuration
类中保存资源内容:
@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 表达式语言来描述将资源文件直接加载到类中的字段中所需的代码。
使用
@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);
}
}
在这里,调用了
ResourceReader#readFileToString
,通过使用
“classpath:”来描述文件的位置——
@Value
注释中的前缀路径。
为了减少 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);
}
}
六,总结
在本文中,回顾了一些
将资源转换为
String
的方法。
首先,看了如何生成一个
Resource
来访问文件,以及如何从
Resource
读取到
String。
接下来,展示了如何隐藏资源加载实现,并通过在
@Configuration
中创建合格的 bean 来允许字符串内容在 bean 之间共享,从而允许字符串自动装配。
最后,使用了 SpEL,它提供了一个紧凑而直接的解决方案,尽管它需要一个自定义帮助函数来阻止它变得过于复杂。
与往常一样,示例代码可以
在 GitHub 上找到