9. 资源处理
Spring Framework 提供了一个抽象,用于从文件系统
servlet 上下文和 Classpath 的 Servlet 上下文。Spring Cloud AWS 增加了对 Amazon S3 服务的支持
使用资源加载器和协议加载和写入资源。org.springframework.core.io.ResourceLoader
s3
资源加载器是 context 模块的一部分,因此使用资源不需要额外的依赖项 处理支持。
9.1. 配置资源加载器
Spring Cloud AWS 不会修改默认资源加载器,除非它遇到带有 XML 命名空间元素的显式配置。 该配置由整个应用程序上下文的一个元素组成,如下所示:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aws-context="http://www.springframework.org/schema/cloud/aws/context"
xsi:schemaLocation="http://www.springframework.org/schema/cloud/aws/context
http://www.springframework.org/schema/cloud/aws/context/spring-cloud-aws-context.xsd">
<aws-context:context-credentials>
...
</aws-context:context-credentials>
<aws-context:context-resource-loader/>
</beans>
9.2. 下载文件
可以通过使用协议引用 Amazon S3 存储桶及其存储桶中的对象来完成下载文件。这
典型模式是 bucket 是全局且唯一的 bucket 名称,object 是有效对象
name 中。对象名称可以是存储桶根文件夹中的文件,也可以是目录中的嵌套文件
在存储桶中。s3
s3://<bucket>/<object>
下一个示例演示了如何使用资源加载器来加载不同的资源。
public class SimpleResourceLoadingBean {
@Autowired
private ResourceLoader resourceLoader;
public void resourceLoadingMethod() throws IOException {
Resource resource = this.resourceLoader.getResource("s3://myBucket/rootFile.log");
Resource secondResource = this.resourceLoader.getResource("s3://myBucket/rootFolder/subFile");
InputStream inputStream = resource.getInputStream();
//read file
}
}
9.3. 上传文件
从 Spring Framework 3.1 开始,资源加载器也可以用于上传带有接口的文件,这是接口的一个特殊化。客户可以上传文件
使用界面。下一个示例演示了使用 resource loader 上传资源。org.springframework.core.io.WritableResource
org.springframework.core.io.ResourceLoader
WritableResource
public class SimpleResourceLoadingBean {
@Autowired
private ResourceLoader resourceLoader;
public void writeResource() throws IOException {
Resource resource = this.resourceLoader.getResource("s3://myBucket/rootFile.log");
WritableResource writableResource = (WritableResource) resource;
try (OutputStream outputStream = writableResource.getOutputStream()) {
outputStream.write("test".getBytes());
}
}
}
9.3.1. 上传多部分文件
Amazon S3 支持将分段上传到
在上传时增加常规吞吐量。Spring Cloud AWS 默认只使用一个线程上传文件,并且
因此不提供并行上传支持。用户可以为资源加载程序配置自定义。资源加载程序将同时将多个线程排队,以使用并行分段上传。org.springframework.core.task.TaskExecutor
使用 10 个线程上传的资源加载程序的配置如下所示
<beans ...>
<aws-context:context-resource-loader task-executor="executor" />
<task:executor id="executor" pool-size="10" queue-capacity="0" rejection-policy="CALLER_RUNS" />
</beans>
Spring Cloud AWS 每个线程最多消耗 5 MB(至少)内存。因此,每个并行线程都会产生
因此,堆中 5 MB 的内存占用量和线程大小 10 将占用多达 50 MB 的堆空间。Spring Cloud
AWS 会尽快释放内存。此外,上面的示例显示没有配置,
因为排队的请求也会消耗内存。 |
9.3.2. 使用 TransferManager 上传
Amazon SDK 还提供了一个高级抽象,可用于上传文件,也可以使用多个线程使用
多部分功能。可以在应用程序中轻松创建 A
代码并注入已创建的预配置客户端
使用 Spring Cloud AWS 资源加载器配置。com.amazonaws.services.s3.transfer.TransferManager
com.amazonaws.services.s3.AmazonS3
此示例显示了如何使用 在应用程序内 从硬盘驱动器上传文件。transferManager
public class SimpleResourceLoadingBean {
@Autowired
private AmazonS3 amazonS3;
public void withTransferManager() {
TransferManager transferManager = new TransferManager(this.amazonS3);
transferManager.upload("myBucket","filename",new File("someFile"));
}
}
9.4. 搜索资源
Spring 资源加载器还支持基于 Ant 样式的路径规范收集资源。Spring Cloud AWS 提供相同的支持来解析存储桶内甚至整个存储桶中的资源。实际的资源加载程序需要 用 Spring Cloud AWS 包装以搜索 s3 存储桶,如果是非 s3 存储桶,则资源加载器 将回退到原来的下一个示例显示了使用不同模式的资源解析。
public class SimpleResourceLoadingBean {
private ResourcePatternResolver resourcePatternResolver;
@Autowired
public void setupResolver(ApplicationContext applicationContext, AmazonS3 amazonS3){
this.resourcePatternResolver = new PathMatchingSimpleStorageResourcePatternResolver(amazonS3, applicationContext);
}
public void resolveAndLoad() throws IOException {
Resource[] allTxtFilesInFolder = this.resourcePatternResolver.getResources("s3://bucket/name/*.txt");
Resource[] allTxtFilesInBucket = this.resourcePatternResolver.getResources("s3://bucket/**/*.txt");
Resource[] allTxtFilesGlobally = this.resourcePatternResolver.getResources("s3://**/*.txt");
}
}
解析所有存储桶中的资源可能非常耗时,具体取决于用户拥有的存储桶数量。 |
9.5. 使用 CloudFormation
CloudFormation 还允许在堆栈创建期间创建存储桶。这些存储桶通常具有生成的名称
必须用作存储桶名称。为了允许应用程序开发人员在其
配置,Spring Cloud AWS 支持解析生成的存储桶名称。
应用程序开发人员可以使用该接口来解析
根据逻辑名称生成的物理名称。org.springframework.cloud.aws.core.env.ResourceIdResolver
下一个示例显示了 CloudFormation 堆栈模板中的存储桶定义。将使用名称创建 Bucket 比如 integrationteststack-sampleBucket-23qysofs62tc2
{
"Resources": {
"sampleBucket": {
"Type": "AWS::S3::Bucket"
}
}
}
应用程序开发人员可以解析该名称并使用它来加载资源,如下面的下一个示例所示。
public class SimpleResourceLoadingBean {
private final ResourceLoader loader;
private final ResourceIdResolver idResolver;
@Autowired
public SimpleResourceLoadingBean(ResourceLoader loader, ResourceIdResolver idResolver) {
this.loader = loader;
this.idResolver = idResolver;
}
public void resolveAndLoad() {
String sampleBucketName = this.idResolver.
resolveToPhysicalResourceId("sampleBucket");
Resource resource = this.loader.
getResource("s3://" + sampleBucketName + "/test");
}
}