spring5.1.3第二章-资源篇

为了最佳地使用和理解应用程序上下文,需要熟悉spring的resource抽象

2. Resources

       spring中如何处理及使用资源

2.1. Introduction

       java.net.url缺少低级资源的访问,只能通过相对路径或servletContext获取

2.2. The Resource Interface

       Resource接口抽象对低级资源的访问
       实用的方法:

  • getInputStream找到并打开文件
  • exists 是否存在
  • isOpen 是否已经被打开,不能多次读取;防止资源泄露
  • getDescription 描述,一般为文件名,或完整的类路径
  • 其他方法:获取资源实际url或file对象

2.3. Built-in Resource Implementations

       spring内置对象如下:

2.3.1. UrlResource

       第一个: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();
		}
	}
2.3.2. ClassPathResource

       该类表示从类路径获取资源,使用线程上下文类加载器,给定的类加载器或给定的类来加载资源
       这个路径表示从程序的根目录,而不是当前类的路径;当使用classpath:开头会隐式创建该实例

Resource urlRes = new ClassPathResource("jdbc.properties");
2.3.3. FileSystemResource

       这是一个resource实现java.io.File和java.nio.file.Path;支持File及URL

2.3.4. ServletContextResource

       用于ServletContext相关的web应用程序根目录的相对路径;依赖于servlet容器

2.3.5. InputStreamResource

       只有resource没有具体的实施才使用

2.3.6. ByteArrayResource

       字节数组实现

实例 描述
UrlResource 基于java.net.URL
ClassPathResource 基于类加载器
FileSystemResource 基于java.io.File,java.nio.fil.Path
ServletContextResource 基于web的ServletContext
InputStreamResource 基于流,没有特定场景时
ByteArrayResource 基于字节

2.4. The ResourceLoader

       所有程序上下文都实现了该接口,用于返回一个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 程序上下文

2.5. The ResourceLoaderAware interface

       该接口是一个特殊的标记接口,标识希望提供ResourceLoader引用的对象
       当一个类实现了该接口并部署到程序上下文中,他被程序上下文识别,会调用setResourceLoader(ResourceLoader),将自身作为入参(所有程序上下文context都实现了ResourceLoader接口)
       spring2.5 开始,可以使用自动装配ResourceLoader的方式替换实现该接口的方式;

2.6. Resources as Dependencies

       资源作为依赖关系注入:


    

2.7. Application Contexts and Resource Paths

       使用resources创建应用程序上下文

2.7.1. Constructing Application Contexts

       使用构造方法创建上下文

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);
2.7.2. Wildcards in Application Context Constructor Resource Paths

       程序上下文构造方法参数中的通配符

/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()

2.7.3. FileSystemResource Caveats

       没有附加到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:为前缀的路径

你可能感兴趣的:(Spring)