`

Spring Resource加载资源

阅读更多

1. Resource简介

在Spring内部,针对于资源文件有一个统一的接口Resource表示。 
其主要实现类有ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、ServletContextResource和InputStreamResource。 
Resource接口中主要定义有以下方法:

  • exists():用于判断对应的资源是否真的存在。
  • isReadable():用于判断对应资源的内容是否可读。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。
  • isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。
  • getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。
  • getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。
  • getInputStream():获取当前资源代表的输入流。除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。

Resource接口的实现类

  • ClassPathResource:通过 ClassPathResource 以类路径的方式进行访问;

  • FileSystemResource:通过 FileSystemResource 以文件系统绝对路径的方式进行访问。FileSystemResource还可以往对应的资源文件里面写内容,当然前提是当前资源文件是可写的,这可以通过其isWritable()方法来判断。FileSystemResource对外开放了对应资源文件的输出流,可以通过getOutputStream()方法获取到。

  • ByteArrayResource是针对于字节数组封装的资源,它的构建需要一个字节数组。

  • ServletContextResource是针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。 
    ServletContextResource持有一个ServletContext的引用,通过 ServletContextResource 以相对于Web应用根目录的方式进行访问。其底层是通过ServletContext的getResource()方法和getResourceAsStream()方法来获取资源的。

  • UrlResource可用来代表URL对应的资源,它对URL做了一个简单的封装。通过给定一个URL地址,我们就能构建一个UrlResource。其底层是通过java.net.URL来访问资源,当然它也支持File格式,如“file:”。

  • ByteArrayResource是针对于字节数组封装的资源,它的构建需要一个字节数组。

  • InputStreamResource是针对于输入流封装的资源,它的构建需要一个输入流。

最常用的有四个:

  • ClassPathResource
  • FileSystemResource
  • ServletContextResource
  • UrlResource

2. 通过ResourceLoader获取资源

ResourceLoader 接口是用来加载 Resource 对象的。它通过一个精确路径的地址信息进行加载Resource,也可以通过Ant风格的地址描述加载匹配的Resource。

Ant路径通配符加载Resource

Ant路径通配符支持?,*,**。 
注意通配符匹配不包括目录分隔符“/”。

通配符 说明
? 匹配任何单字符
* 匹配0或者任意数量的字符
** 匹配0或者更多的目录

匹配样例

URL路径 说明
/app/*.x 匹配(Matches)所有在app路径下的.x文件
/app/p?ttern 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern
/**/example 匹配(Matches) /app/example, /app/foo/example, 和 /example
/app/**/dir/file. 匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java
/*/.jsp 匹配(Matches)任何的.jsp 文件

属性: 
最长匹配原则(has more characters) 
说明,URL请求/app/dir/file.jsp,现在存在两个路径匹配模式/**/*.jsp/app/dir/*.jsp,那么会根据模式/app/dir/*.jsp来匹配

精确路径加载Resource

为了更加精确表示Resource类型,可以加入对应的前缀标识来说明。 
如路径:com/baobaotao/beanfactory/bean.xml

地址前缀 示例 对应资源类型
classpath: classpath:com/baobaotao/beanfactory/bean.xml 从类路径中加载资源,资源文件可以在标准的文件系统中,也可以在jar或者zip的类包中
file: file:/conf/com/baobaotao/beanfactory/bean.xml 使用URLResource从文件系统目录中装载资源,可采用绝对或相对路径。
file: file:/conf/com/baobaotao/beanfactory/bean.xml 使用URLResource从文件系统目录中装载资源,可采用绝对或相对路径。
http:// http://www.baobaotao/resource/bean.xml  
ftp: ftp://www.baobaotao.com/resource/bean.xml 使用UrlResource从FTP服务器中装载资源
com/baobaotao/beanfatory/beans.xml 根据ApplicationContext具体实现类采用对应的类型的Resource  

classpath与classpath*的区别

准备工作

在项目的“resources”创建“META-INF”目录,然后在其下创建一个“INDEX.LIST”文件。同时在“org.springframework.beans-3.0.5.RELEASE.jar”和“org.springframework.context-3.0.5.RELEASE.jar”两个jar包里也存在相同目录和文件。然后创建一个“LICENSE”文件,该文件存在于“com.springsource.cn.sf.cglib-2.2.0.jar”里。

“classpath”: 用于加载类路径(包括jar包)中的一个且仅一个资源;对于多个匹配的也只返回一个,所以如果需要多个匹配的请考虑“classpath*:”前缀; 
对于匹配多个资源的情况下,会优先返回相对于本工程中下面的classpath路径下的匹配的资源。

@Test
public void testClasspathPrefix() throws IOException {
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    //只加载一个绝对匹配Resource,且通过ResourceLoader.getResource进行加载
    Resource[] resources=resolver.getResources("classpath:META-INF/INDEX.LIST");
    Assert.assertEquals(1, resources.length);
    //只加载一个匹配的Resource,且通过ResourceLoader.getResource进行加载
    resources = resolver.getResources("classpath:META-INF/*.LIST");
    Assert.assertTrue(resources.length == 1);           
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

“classpath*”: 用于加载类路径(包括jar包)中的所有匹配的资源。带通配符的classpath使用“ClassLoader”的“Enumeration getResources(String name)”方法来查找通配符之前的资源,然后通过模式匹配来获取匹配的资源。如“classpath:META-INF/*.LIST”将首先加载通配符之前的目录“META-INF”,然后再遍历路径进行子路径匹配从而获取匹配的资源。

@Test
public void testClasspathAsteriskPrefix () throws IOException {
     ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();      
     //将加载多个绝对匹配的所有Resource
    //将首先通过ClassLoader.getResources("META-INF")加载非模式路径部分
    //然后进行遍历模式匹配
    Resource[] resources=resolver.getResources("classpath*:META-INF/INDEX.LIST");
    Assert.assertTrue(resources.length > 1);    
    //将加载多个模式匹配的Resource
    resources = resolver.getResources("classpath*:META-INF/*.LIST");
    Assert.assertTrue(resources.length > 1);  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

结论

在声明资源地址路径的时候,可以混合使用Ant路径通配符和前缀标识。 
如: 
classpath:com/**/test.xml : 匹配com路径下(当前目录及其子孙目录)的test.xml文件;

分享到:
评论

相关推荐

    Spring实战之使用ClassPathResource加载xml资源示例

    主要介绍了Spring实战之使用ClassPathResource加载xml资源,结合实例形式分析了Spring使用ClassPathResource加载xml资源的具体实现步骤与相关操作技巧,需要的朋友可以参考下

    cas-addon-spring-resource-reloading-support:与处理 Spring Framework 资源运行时重新加载有关的常用实用程序

    与在 CAS 服务器的上下文中处理 Spring Framework 资源运行时重新加载有关的通用实用程序。 虽然这个库的主要原因是支持需要资源重新加载功能的各种 CAS 插件,但这个项目不携带任何 CAS 特定位,并且足够通用以...

    Spring攻略(第二版 中文高清版).part2

    2.10 加载外部资源 82 2.10.1 问题 82 2.10.2 解决方案 83 2.10.3 工作原理 83 2.11 创建Bean后处理器 85 2.11.1 问题 85 2.11.2 解决方案 85 2.11.3 工作原理 86 2.12 外部化Bean配置 89 2.12.1...

    spring源代码

    //只加载一个绝对匹配Resource,且通过ResourceLoader.getResource进行加载 Resource[] resources = resolver.getResources("classpath:META-INF/INDEX.LIST"); Assert.assertEquals(1, resources.length); //...

    Spring中文帮助文档

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring API

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring攻略(第二版 中文高清版).part1

    2.10 加载外部资源 82 2.10.1 问题 82 2.10.2 解决方案 83 2.10.3 工作原理 83 2.11 创建Bean后处理器 85 2.11.1 问题 85 2.11.2 解决方案 85 2.11.3 工作原理 86 2.12 外部化Bean配置 89 2.12.1...

    spring2.5.6源码

    第二句就是整个类中最重要的地方了,顾名思义,它的目的是通过XmlBeanDefinitionReader这个XML的Reader从资源resource中(也就是你的配置文件)读取bean的定义。接下来我们打开XmlBeanDefinitionReader的...

    Java加载资源文件的两种方法

    处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都...  在了解了Java加载资源文件的机制后,以上这两个问题便迎刃而解了。  对于第一个问题,答案是:请将你的资源文件放在c

    注入资源:使用Java读取资源内容的简单便捷方法

    使用@InjectResources是加载和解析资源内容的最简单,最方便的方法,而无需打开/关闭流并处理I / O异常的样板代码。 该库由 ,流畅的Java DSL以及 , 和的扩展组成,这些扩展允许使用简单的批注进行此操作。例子...

    单点登录源码

    zheng.jprogress.js | 加载进度条插件 | [https://github.com/shuzheng/zheng.jprogress.js](https://github.com/shuzheng/zheng.jprogress.js) zheng.jtotop.js | 返回顶部插件 | ...

    day020-继承加强和设计模式代码和笔记.rar

    缺点:类加载效率低,并且static修饰的成员占用资源。 2. 懒汉模式:懒加载模式 (优化方式:双重校验锁) 优点:节省资源,在需要的时候创建对象。 缺点:线程不安全。获取对象的时候,效率...

    J2EE应用开发详解

    364 19.5.1 管理员登录 364 19.5.2 模块管理 374 19.5.3 角色数据操作 383 19.5.4 资源操作 391 19.5.5 用户管理 394 19.6 小结 404 第20章 航空订票系统(JSF/Richfaces+EJB+JPA) 405 20.1 需求分析 405 20.2 基本...

    cms后台管理

    <import resource="jeecms-servlet-front-action.xml"/>代码 找到jeecms-servlet-front-action.xml,在此配置文件中有 <bean id="dynamicAct" class="com.jeecms.cms.action.front.DynamicPageAct"/> 可以找到类...

Global site tag (gtag.js) - Google Analytics