添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

spring 资源加载机制


Spring资源加载机制介绍

Java标准API java.net.URL 能够处理URL资源,但是却不能处理”低等级”的资源,比如,没有标准化的 URL 实现用来加载类路径的资源, 虽然可以注册用于特殊URL前缀的新处理程序(类似于用于诸如http:的现有前缀的处理程序),但这通常相当复杂,并且URL接口仍然缺少某些理想的功能,例如用于检查是否存在的方法 指向的资源。

Resource接口定义

Spring的 Resource 接口抽象出了处理低级资源的方法:

public interface Resource extends InputStreamSource {
    boolean exists();
    boolean isOpen();
    URL getURL() throws IOException;
    File getFile() throws IOException;
    Resource createRelative(String relativePath) throws IOException;
    String getFilename();
    String getDescription();
}

Resource 集成了 InputStreamSource 接口:

public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}

Resource 中比较重要的方法是:

如果其底层实现支持的话,其他的方法则可以获取 URL File 对象。

Spring本身许多需要操作资源的方法签名都是使用 Resource 接口,还有一部分Spring的API接收资源的路径,并且会根据路径的前缀自动创建合适的 Resource 对象。

尽管Spring经常使用 Resource 接口,但实际上,在自己的代码中单独使用 Resource 接口类作为通用实用工具类来访问资源非常有用,即使我们的代码不了解或不关心其他Spring的任何东西

Resource API并没有替换任何功能,只是在相关的场景进行包装,比如, UrlResource 包装了 URL ,并且实际上是使用这个 URL 来进行相关操作

Spring提供的 Resource 实现

UrlResource

UrlResource 包装了 java.net.URL ,可以被用来获取常规资源,比如:文件、http资源、ftp资源,所有的URL都使用 String 进行表述,并且都包含了适当的资源路径前缀。 file: 用于读取文件系统, http: 获取Http协议资源, ftp: 获取FTP文件等

UrlResource 可以通过构造器显式的创建,但是通常都是调用的Spring API接收 String 类型的路径参数自动创建合适的 Resource 实现类,当其无法识别路径前缀才创建 UrlResource

ClassPathResource

ClassPathResource 用于加载类路径的资源,使用当前线程的类加载器或给定的类加载器进行资源加载。如果类路径资源已经被解压到文件系统,则会将资源加载为 java.io.File ,为了解决这个问题,许多 Resource 的实现总是支持解析为 java.net.URL

FileSystemResource

支持处理 java.io.File java.nio.file.Path

ServletContextResource

ServletContext资源的 Resource 实现,用于解析相关Web应用程序根目录中的相对路径。

它始终支持流访问和 URL 访问,但仅在Jar包被解压才允许 java.io.File 访问。 不管是解压还是直接访问文件系统、或者直接从JAR或其他类似数据库访问,取决于Servlet容器。

InputStreamResource

适用于给定的 InputStream ,应该被用于未指定的 Resource 的情况下进行适配。通常情况下 isOpen() 返回 true ,意味着不能多次读取流。

ByteArrayResource

将会创建一个 ByteArrayResource 基于给定的字节数组,比使用 InputStreamResource 更有效。

ResourceLoader 接口

ResourceLoader 接口需要被那些能够加载资源的对象实现:

public interface ResourceLoader {
    Resource getResource(String location);
}

所有的 ApplicationContext 都实现了 ResourceLoader 接口,因此可以被用来获取相关的 Resource 实例。

更具具体的 ApplicationContext 实现类,通常不需要加资源路径的前缀,比如通过 ClassPathXmlApplicationContext 加载:

public void loadresource(){
  Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
}

以上代码将返回 ClassPathResource ,如果换成 FileSystemXmlApplicationContext ,将会得到 FileSystemResource ,而对于 WebApplicationContext 来说,将会返回 ServletContextResource

如果需要强制使用类路径加载则也可以指定路径前缀 classpath:

public void loadresource(){
    Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
}

同样的,指定使用 UrlResource 需要指定 file http 前缀:

public void loadresource(){