Spring Resources

Spring 提供了多种方法访问各种资源文件。

Resource 接口

相对标准 url 访问机制,spring 的 Resource 接口对抽象底层资源的访问提供了一套更好的机制。

  1. public interface Resource extends InputStreamSource {
  2. boolean exists();
  3. boolean isOpen();
  4. URL getURL() throws IOException;
  5. File getFile() throws IOException;
  6. Resource createRelative(String relativePath) throws IOException;
  7. String getFilename();
  8. String getDescription();
  9. }

Resource 接口里的最重要的几个方法:

  • getInputStream() - 定位并且打开当前资源,返回当前资源的 InputStream
  • exists() - 返回一个 boolean,表示当前资源是否真的存在。
  • isOpen() - 返回一个 boolean,表示当前资源是否是一个已打开的输入流。
  • getDescription() - 返回当前资源的描述,当处理资源出错时,资源的描述会用于错误信息的输出。一般来说,资源的描述是一个完全限定的文件名称,或者是当前资源的真实 url。

内置的 Resource 实现

spring 直接提供了多种开箱即用的 Resource 实现。

  • UrlResource - UrlResource 封装了一个 java.net.URL 对象,用来访问 URL 可以正常访问的任意对象,比如文件、an HTTP target, an FTP target, 等等。
  • ClassPathResource - ClassPathResource 可以从类路径上加载资源,其可以使用线程上下文加载器、指定加载器或指定的 class 类型中的任意一个来加载资源。
  • FileSystemResource - 这是针对 java.io.File 提供的 Resource 实现。
  • ServletContextResource - 这是为了获取 web 根路径的 ServletContext 资源而提供的 Resource 实现。
  • InputStreamResource - 这是针对 InputStream 提供的 Resource 实现。
  • ByteArrayResource - 这是针对字节数组提供的 Resource 实现。可以通过一个字节数组来创建 ByteArrayResource。

ResourceLoader 接口

ResourceLoader 接口是用来加载 Resource 对象的。

  1. public interface ResourceLoader {
  2. Resource getResource(String location);
  3. }

spring 里所有的 ApplicationContext 都实现了 ResourceLoader 接口,因此,所有 ApplicationContext 都可以通过 getResource() 方法获取 Resource 实例。

示例:

  1. Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
  2. Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
  3. Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
  4. Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");

下表列举了 spring 根据各种位置路径加载资源的策略:

前缀 例子 解释
classpath: classpath:com/myapp/config.xml 从类路径加载
file: file:///data/config.xml 以 URL 形式从文件系统加载
http: http://myserver/logo.png 以 URL 形式加载
(none) /data/config.xml 由底层的 ApplicationContext 实现决定

ResourceLoaderAware 接口

ResourceLoaderAware 是一个特殊的标记接口,用来标记提供 ResourceLoader 引用的对象。

  1. public interface ResourceLoaderAware {
  2. void setResourceLoader(ResourceLoader resourceLoader);
  3. }

当将一个 ResourceLoaderAware 接口的实现类部署到应用上下文时(此类会作为一个 spring 管理的 bean), 应用上下文会识别出此为一个 ResourceLoaderAware 对象,并将自身作为一个参数来调用 setResourceLoader() 函数,如此,该实现类便可使用 ResourceLoader 获取 Resource 实例来加载你所需要的资源。

资源依赖

如果 bean 本身将通过某种动态过程来确定和提供资源路径,那么 bean 可以使用 ResourceLoader 接口来加载资源。

请看如下 xml 示例:

  1. <bean id="myBean" class="...">
  2. <property name="template" value="some/resource/path/myTemplate.txt"/>
  3. </bean>

请注意,配置中引用的模板资源路径没有前缀,因为应用程序上下文本身将用作 ResourceLoader,资源本身将通过 ClassPathResource,FileSystemResource 或 ServletContextResource(根据需要)加载,具体取决于上下文的确切类型。

如果需要强制使用特定的资源类型,则可以使用前缀。 以下两个示例显示如何强制使用 ClassPathResource 和 UrlResource(后者用于访问文件系统文件)。

  1. <property name="template" value="classpath:some/resource/path/myTemplate.txt">
  2. <property name="template" value="file:///some/resource/path/myTemplate.txt"/>

应用上下文和资源路径

构造应用上下文

spring 中的 ApplicationContext 的构造器通常可以使用字符串或字符串数组所指代的(多个)资源(如 xml 文件)来构造当前上下文。

示例:

  1. ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
  2. ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
  3. ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
  4. ApplicationContext ctx = new ClassPathXmlApplicationContext(
  5. new String[] {"services.xml", "daos.xml"}, MessengerService.class);

使用通配符构造应用上下文

ApplicationContext 构造器的中的资源路径可以是单一的路径(即一对一地映射到目标资源);也可以是通配符形式——可包含 classpath*:也可以是前缀或 ant 风格的正则表达式(使用 spring 的 PathMatcher 来匹配)。

示例:

  1. ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");

使用 classpath* 表示类路径下所有匹配文件名称的资源都会被获取(本质上就是调用了 ClassLoader.getResources(…) 方法),接着将获取到的资源组装成最终的应用上下文。

在位置路径的其余部分,classpath*: 前缀可以与 PathMatcher 结合使用,如:classpath*:META-INF/*-beans.xml

示例代码

我的示例代码地址:spring-tutorial-core-resouces

参考资料