4. Resources
4.1. Introduction
Javarsquo;s standard java.net.URL class and standard handlers for various URL prefixes, unfortunately, are not quite adequate enough for all access to low-level resources. For example, there is no standardized URL implementation that may be used to access a resource that needs to be obtained from the classpath or relative to a ServletContext. While it is possible to register new handlers for specialized URL prefixes (similar to existing handlers for prefixes such as http:), this is generally quite complicated, and the URL interface still lacks some desirable functionality, such as a method to check for the existence of the resource being pointed to.
4.2. The Resource Interface
Springrsquo;s Resource interface is meant to be a more capable interface for abstracting access to low-level resources. The following listing shows the Resource interface definition:
public interface InputStreamSource {
boolean exists();
boolean isOpen();
URL getURL() throws IOException;
File getFile() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Some of the most important methods from the Resource interface are:
- getInputStream(): Locates and opens the resource, returning an InputStream for reading from the resource. It is expected that each invocation returns a fresh InputStream. It is the responsibility of the caller to close the stream.
- exists(): Returns a boolean indicating whether this resource actually exists in physical form.
- isOpen(): Returns a boolean indicating whether this resource represents a handle with an open stream. If true, the InputStream cannot be read multiple times and must be read once only and then closed to avoid resource leaks. Returns false for all usual resource implementations, with the exception of InputStreamResource.
- getDescription(): Returns a description for this resource, to be used for error output when working with the resource. This is often the fully qualified file name or the actual URL of the resource.
Other methods let you obtain an actual URL or File object representing the resource (if the underlying implementation is compatible and supports that functionality).
Spring itself uses the Resource abstraction extensively, as an argument type in many method signatures when a resource is needed. Other methods in some Spring APIs (such as the constructors to various ApplicationContext implementations) take a String which in unadorned or simple form is used to create a Resource appropriate to that context implementation or, via special prefixes on the String path, let the caller specify that a specific Resource implementation must be created and used.
While the Resource interface is used a lot with Spring and by Spring, it is actually very useful to use as a general utility class by itself in your own code, for access to resources, even when your code does not know or care about any other parts of Spring. While this couples your code to Spring, it really only couples it to this small set of utility classes, which serve as a more capable replacement for URL and can be considered equivalent to any other library you would use for this purpose.
The Resource abstraction does not replace functionality. It wraps it where possible. For example, a UrlResource wraps a URL and uses the wrapped URL to do its work.
4.3. Built-in Resource Implementations
Spring includes the following Resource implementations:
4.3.1. UrlResource
UrlResource wraps a java.net.URL and can be used to access any object that is normally accessible with a URL, such as files, an HTTP target, an FTP target, and others. All URLs have a standardized String representation, such that appropriate standardized prefixes are used to indicate one URL type from another. This includes file: for accessing filesystem paths, http: for accessing resources through the HTTP protocol, ftp: for accessing resources through FTP, and others.
A UrlResource is created by Java code by explicitly using the UrlResource constructor but is often created implicitly when you call an API method that takes a String argument meant to represent a path. For the latter case, a JavaBeans PropertyEditor ultimately decides which type of Resource to create. If the path string contains well-known (to it, that is) prefix (such as classpath:), it creates an appropriate specialized Resource for that prefix. However, if it does not recognize the prefix, it assume the string is a standard URL string and creates a UrlResource.
4.3.2. ClassPathResource
This class represents a resource that should be obtained from the classpath. It uses either the thread context class loader, a given class loader, or a given class for loading resources.
This Resource implementation supports resolution as java.io.File if the class path resource resides in the file system but not for classpath resources that reside in a jar and have not been expanded (by the servlet engine or whatever the environment is) to the filesystem. To address this, the various Resource implementations always support resolution as a java.net.URL.
A ClassPathResource is created by Java code by explicitly using the ClassPathResource constructor but is often created implicitly when you call an API method that takes a String argument meant to represent a path. For the latter case, a JavaBeans PropertyEditor recognizes the special prefix, classpath:, on the string path and creates a ClassPathResource in that case.
4.3.3. FileSystemResource
This is a Resource implementation for java.io.File and java.nio.file.Path handles. It supports resolution as a File and as a
剩余内容已隐藏,支付完成后下载完整资料
Chapter 4. 资源
4.1. 简介
Java标准的 java.net.URL类和多种URL前缀处理类并不能很好地满足所有底层资源访问的需要。比如,还没有能从类路径或者相对于ServletContext 的路径中获得资源的标准URL实现。虽然能为特定的URL前缀注册新的处理类(类似已有前缀 http: 的处理类),但是这样做通常比较复杂,而且URL接口还缺少一些有用的功能,比如检查指向的资源是否存在的方法。
4.2. Resource接口
Spring的 Resource 接口是为了提供更强的访问底层资源能力的抽象。
public interface InputStreamSource {
boolean exists();
boolean isOpen();
URL getURL() throws IOException;
File getFile() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Resource 接口一些比较重要的方法如下:
getInputStream(): 定位并打开资源,返回读取此资源的一个 InputStream。每次调用预期会返回一个新的 InputStream,由调用者负责关闭这个流。
exists(): 返回标识这个资源在物理上是否的确存在的 boolean 值。
isOpen(): 返回标识这个资源是否有已打开流的处理类的 boolean 值。如果为 true,则此InputStream 就不能被多次读取, 而且只能被读取一次然后关闭以避免资源泄漏。除了 InputStreamResource,常见的resource实现都会返回 false。
getDescription(): 返回资源的描述,一般在与此资源相关的错误输出时使用。此描述通常是完整的文件名或实际的URL地址。
其它方法让你获得表示该资源的实际的 URL 或 File 对象(如果隐含的实现支持该方法并保持一致的话)。
Spring自身处理资源请求的多种方法声明中将Resource 抽象作为参数而广泛地使用。 Spring APIs中的一些其它方法(比如许多ApplicationContext的实现构造函数),使用普通格式的 String 来创建与context相符的Resource,也可以使用特殊的路径String前缀来让调用者指定创建和使用特定的 Resource 实现。
Resource不仅被Spring自身大量地使用,它也非常适合在你自己的代码中独立作为辅助类使用。 用户代码甚至可以在不用关心Spring其它部分的情况下访问资源。这样的确会造成代码与Spring之间的耦合,但也仅仅是与很少量的辅助类耦合。这些类可以作为比 URL 更有效的替代,而且与为这个目的而使用其它类库基本相似。
需要注意的是 Resource 抽象并没有改变功能:它尽量使用封装。 比如 UrlResource 封装了URL,然后使用被封装的 URL 来工作。
4.3. 内置 Resource 实现
Spring提供了很多 Resource 的实现:
4.3.1. UrlResource
UrlResource 封装了java.net.URL,它能够被用来访问任何通过URL可以获得的对象,例如:文件、HTTP对象、FTP对象等。所有的URL都有个标准的 String表示,这些标准前缀可以标识不同的URL类型,包括file:访问文件系统路径,http: 通过HTTP协议访问的资源,ftp: 通过FTP访问的资源等等。
UrlResource 对象可以在Java代码中显式地使用 UrlResource 构造函数来创建。但更多的是通过调用带表示路径的 String 参数的API函数隐式地创建。在后一种情况下,JavaBeans的 PropertyEditor 会最终决定哪种类型的 Resource 被创建。如果这个字符串包含一些众所周知的前缀,比如 classpath:,它就会创建一个对应的已串行化的 Resource。 然而,如果不能分辨出这个前缀,就会假定它是个标准的URL字符串,然后创建UrlResource。
4.3.2. ClassPathResource
这个类标识从classpath获得的资源。它会使用线程context的类加载器(class loader)、给定的类加载器或者用来载入资源的给定类。
如果类路径上的资源存在于文件系统里,这个 Resource 的实现会提供类似于java.io.File的功能。而如果资源是存在于还未解开(被servlet引擎或其它的环境解开)的jar包中,这些 Resource 实现会提供类似于java.net.URL 的功能。
ClassPathResource对象可以在Java代码中显式地使用ClassPathResource 构造函数来创建。但更多的是通过调用带表示路径的String参数的API函数隐式地创建。在后一种情况下,JavaBeans的 PropertyEditor 会分辨字符串中 classpath: 前缀,然后相应创建 ClassPathResource。
4.3.3. FileSystemResource
这是为处理 java.io.File 而准备的Resource实现。它既可以作为File提供,也可以作为URL。
4.3.4. ServletContextResource
这是为 ServletContext 资源提供的 Resource 实现,它负责解析相关web应用根目录中的相对路径。
它始终支持以流和URL的方式访问。 但是只有当web应用包被解开并且资源在文件系统的物理路径上时,才允许以 java.io.File 方式访问。是否解开并且在文件系统中访问,还是直接从JAR包访问或以其它方式访问如DB(这是可以想象的),仅取决于Servlet容器。
4.3.5. InputStreamResource
这是为给定的 InputStream 而准备的 Resource 实现。它只有在没有其它合适的 Resource 实现时才使用。而且,只要有可能就尽量使用 ByteArrayResource 或者其它基于文件的Resource 实现。
与其它 Resource 实现不同的是,这是个 已经 打开资源的描述符-因此 isOpen() 函数返回 true。 如果你需要在其它位置保持这个资源的描述符或者多次读取一个流,不要使用它。
4.3.6. ByteArrayResource
这是为给定的byte数组准备的 Resource 实现。 它会为给定的byte数组构造一个 ByteArrayInputStream。
它在从任何给定的byte数组读取内容时很有用,因为不用转换成单一作用的 InputStreamResource。
4.4. ResourceLoader接口
ResourceLoader 接口由能返回(或者载入)Resource 实例的对象来实现。
public interface ResourceLoader {
Resource getResource(String location);
}
所有的application context都实现了 ResourceLoader 接口, 因此它们可以用来获取Resource实例。
当你调用特定application context的 getResource() 方法, 而且资源路径并没有特定的前缀时,你将获得与该application context相应的 Resource 类型。例如:假定下面的代码片断是基于ClassPathXmlApplicationContext 实例上执行的:
Resource template = ctx.getResource('some/resource/path/myTemplate.txt');
这将返回ClassPathResource;如果是基于FileSystemXmlApplicationContext 实例上执行的,那你将获得FileSystemResource。而对于 WebApplicationContext 你将获得ServletContextResource,依此类推。这样你可以在特定的application context中用流行的方法载入资源。
另一方面,无论什么类型的application context, 你可以通过使用特定的前缀 classpath: 强制使用ClassPathResource。
Resource template = ctx.getResource('classpath:some/resource/path/myTemplate.txt');
同样的,你可以用任何标准的 java.net.URL 前缀,强制使用 UrlResource :
Resource template = ctx.getResource('file:/some/resource/path/myTemplate.txt');
Resource template = ctx.getResource('http://myhost.com/resource/path/myTemplate.txt');
4.5. ResourceLoaderAware 接口
ResourceLoaderAware是特殊的标记接口,它希望拥有一个ResourceLoader 引用的对象。
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
当实现了 ResourceLoaderAware接口的类部署到application context(比如受Spring管理的bean)中时,它会被application context识别为 ResourceLoaderAware。 接着application context会调用setResourceLoader(ResourceLoader)方法,并把自身作为参数传入该方法(记住,所有Spring里的application context都实现了ResourceLoader接口)。
既然 ApplicationContext 就是ResourceLoader,那么该bean就可以实现 ApplicationContextAware接口并直接使用所提供的application context来载入资源,但是通常更适合使用特定的满足所有需要的 ResourceLoader实现。 这样一来,代码只需要依赖于可以看作辅助接口的资源载入接口,而不用依赖于整个Spring ApplicationContext 接口。
从Spring 2.5开始, 你可以使用ResourceLoader 的自动装配来代替实现 ResourceLoaderAware 接口。“传统的” constructor及 byType的自动装配模式 (Section 3.3.5, “自动装配(autowire)协作者”已有论述)现在可以分别为构造方法参数及setter方法参数提供 ResourceLoader 类型的依赖。请使用新式的基于注解的自动装配特性以提供更大的灵活性(包括装配属性及多个方法参数的能力)。在这种情况下,只要属性、构造方法或者方法被 @Autowired注解修饰,ResourceLoader 就会被装配到需要ResourceLoader类型的属性、构造方法参数或者方法参数中。请查看章节 Section 3.11.1, “@Autowired”以了解进一步的信息。
4.6. 把Resource作为属性来配置
如果bean自身希望通过一些动态方式决定和提供资源路径,那么让这个bean通过 ResourceLoader 接口去载入资源就很有意义了。考虑一个载入某类模板的例子,其中需要哪种特殊类型由用户的角色决定。 如果同时资源是静态的,完全不使用 ResourceLoader 接口很有意义, 这样只需让这些bean暴露所需的 Resource 属性,并保证他们会被注入。
让注入这些属性的工作变得如此容易的原因是,所有的application context注册并使用了能把 String 路径变为 Resource 对象的特殊 PropertyEditor JavaBeans。因此如果 myBean 有 Resource 类型的template属性, 那它就能够使用简单的字符串配置该资源,如下所示:
lt;bean id='myBean' class='...'gt;
lt;property name='templa
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[235621],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。