为了最佳地使用和理解应用程序上下文,需要熟悉spring的resource抽象
spring中如何处理及使用资源
java.net.url缺少低级资源的访问,只能通过相对路径或servletContext获取
Resource接口抽象对低级资源的访问
实用的方法:
spring内置对象如下:
第一个:urlResource
该类包装java.net.url,可以访问URL访问的任何对象;包括file:,http:,ftp:的资源\
该类可以通过构造方法直接创建使用;一般在spring中,在使用String表示的资源路径作为参数的api时,都会隐式的创建该对象。在隐式使用场景中,javabeaan会根据程序可识别的前缀(如:classpath:)来创建专用的Resource接口实现,否则都会默认为是一个标准的url而使用该类实例。
@Test
public void urlResourceTest() {
try {
Resource urlRes = new UrlResource("file:H:\\workerSpace-My\\workspace-Spring\\springTest\\src\\main\\resources\\jdbc.properties");
if(urlRes.exists() && !urlRes.isOpen()) {
File file = urlRes.getFile();
BufferedReader reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
while ((tempString = reader.readLine()) != null) {
// 显示行号
System.out.println("line " + line + ": " + tempString);
line++;
}
reader.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
该类表示从类路径获取资源,使用线程上下文类加载器,给定的类加载器或给定的类来加载资源
这个路径表示从程序的根目录,而不是当前类的路径;当使用classpath:开头会隐式创建该实例
Resource urlRes = new ClassPathResource("jdbc.properties");
这是一个resource实现java.io.File和java.nio.file.Path;支持File及URL
用于ServletContext相关的web应用程序根目录的相对路径;依赖于servlet容器
只有resource没有具体的实施才使用
字节数组实现
实例 | 描述 |
---|---|
UrlResource | 基于java.net.URL |
ClassPathResource | 基于类加载器 |
FileSystemResource | 基于java.io.File,java.nio.fil.Path |
ServletContextResource | 基于web的ServletContext |
InputStreamResource | 基于流,没有特定场景时 |
ByteArrayResource | 基于字节 |
所有程序上下文都实现了该接口,用于返回一个Resource实例;如果是没有特定前缀的路径,返回的实例是符合程序上线文的类型
比如:ClassPathXmlApplicationContext获取,则返回ClassPathResource的实例;FileSystemXmlApplicationContext获取,返回FileSystemResource的实例;WebApplicationContext返回ServletContextResource。如果路径是带前缀的,如:classpath:/file:/http:返回的实例则不与程序上下文相关
转换策略:
Prefix | Example | Explanation |
---|---|---|
classpath: | classpath:com/myapp/config.xml | 从classpath路径加载 |
file: | file:///data/config.xml | 从系统url中加载/FileSystemResource |
http: | http://myserver/logo.png | 作为url加载 |
(none) | /data/config.xml | 程序上下文 |
该接口是一个特殊的标记接口,标识希望提供ResourceLoader引用的对象
当一个类实现了该接口并部署到程序上下文中,他被程序上下文识别,会调用setResourceLoader(ResourceLoader),将自身作为入参(所有程序上下文context都实现了ResourceLoader接口)
spring2.5 开始,可以使用自动装配ResourceLoader的方式替换实现该接口的方式;
资源作为依赖关系注入:
使用resources创建应用程序上下文
使用构造方法创建上下文
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
//这个数组中的资源不能有前导路径,这些文件需要与后面的class在同一个路径中
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
程序上下文构造方法参数中的通配符
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
//将路径下的所有资源组合在一起,形成上下文定义
/**
*这个特殊的前缀指定必须获得与给定名称匹配的所有类路径资源(在内部,
*这主要通过调用ClassLoader.get.(......)),
*然后合并以形成最终的应用程序上下文定义。
*/
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
与Ant-style模式结合使用时,除非实际目标文件驻留在文件系统中,否则在模式启动之前,只能与至少一个根目录一起可靠地工作。这意味着一种模式 classpath*?.xml可能无法从jar文件的根目录中检索文件,而只能从扩展目录的根目录中检索文件。
spring检索的能力来自jdk的ClassLoader.getResources()
没有附加到FileSystemApplicationContext(即,当FileSystemApplicationContext不是实际的ResourceLoader时)的FileSystemResource按预期处理绝对路径和相对路径。相对路径相对于当前工作目录,而绝对路径相对于文件系统的根。
然而,由于向后兼容性(历史)的原因,当FileSystemApplicationContext是ResourceLoader时,此更改。FileSystemApplicationContext强制所有附加的FileSystemResource实例将所有位置路径视为相对路径,无论它们是否以斜杠开头
//这两种方式是一样的
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
//FileSystemXmlApplicationContext ctx 也是等效的
ctx.getResource("some/resource/path/myTemplate.txt");
ctx.getResource("/some/resource/path/myTemplate.txt");
故实际使用时,如果需要使用绝对路径,不要使用FileSystem相关的,而是使用UrlResource;即file:为前缀的路径