目录
介绍
Resource接口
内置Resource实现
1.UrlResource
2.ClassPathResource
3.FileSystemResource
4.ServletContextResource
5.InputStreamResource
6.ByteArrayResource
ResourceLoader
ResourceLoaderAware接口
作为依赖的资源
翻译源:Spring官方文档
介绍
Java标准java.net.URL类与与针对不同前缀的的handler并不足以应对一切对低级资源的访问。
eg:没有标准的URL实现可以用于访问从classpath下获取的资源或相对于ServletContext的资源。
虽然可以为特定的URL前缀注册新的handler,但这个过程较为复杂并且URL接口本身缺乏一些必要的功能(eg:检测资源存在)。
Resource接口
public interface Resource extends 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;
}
note:Resource接口是一个拥有更多功能的对低层资源访问抽象的接口
ps:isOpen():返回一个boolean值,用于指示资源是否为代表open流的句柄。如果返回true,表示为了防止资源泄露,资源只能被读取一次然后关闭。除了InputStreamSource,所以常规资源都将返回false。
ps:getDescription():返回一个资源描述,通常是完整文件名或资源的真实URL。
Resource作为许多需要资源的方法的参数类型,大量用于Spring框架自身。
一些Spring API(eg:各种ApplicationContext的构造器)的方法通过简单形式的字符串为context实现创建合适的Resource,或通过Spring路径上的特定前缀指定创建与使用的特定的Resource实现。
为了便于访问资源,Resource接口可以直接用于开发者自己的代码中,而无需关心Spring的其他组件。
这样即使会产生与Spring框架的耦合,也只是与Spring中一个很小的工具类集合耦合,可以被等价认定为为了访问资源使用的其他库。
Resource只是包装功能而不是替换功能,例如,UrlResource包装了URL,底层的工作还是由URL完成。
内置Resource实现
1.UrlResource
UrlResource包装了java.net.URL,用于访问可以通过URL访问的资源(eg:文件、HTTP目标、FTP目标)。
UrlResource通过Java代码显示使用UrlResource构造器创建,不过通常会被需要使用资源的API方法隐式创建。(eg:PropertyEditor决定创建的Resource的类型。)
2.ClassPathResource
ClassPathResource代表了可以从classpath上获取的的资源。它使用线程上下文类加载器或给定的类加载器或给定的用于加载资源的类。
如果资源位于文件系统,Resouce实现支持类似java.io.File的解析。
为了应对需要解析资源的多种类型,Resource实现总是支持java.net.URL的解析。
3.FileSystemResource
针对java.io.File的Resource实现,支持java.net.URL与java.io.File解析。
4.ServletContextResource
针对ServletContext资源的Resource实现,解释web应用根目录下的相对路径。
ServletContextResource支持流访问与URL访问,只有当web应用档案文件解压到文件系统中时,才会使用java.io.File访问。
无论采用何种方式访问,资源都必需依赖于Servlet容器。
5.InputStreamResource
用于给定InputStream的Resource实现。只有当没有特定的Resource实现适用时才会被使用。
这个描述符用于已经open的资源,即isOpen()方法返回true。
如果需要将资源描述符保留在某些地方,或者需要多次读取的地方不要使用此实现。
6.ByteArrayResource
用于给定byte数组的Resource实现。它为给定的byte数组创建了一个ByteArrayResource。
如果需要加载给定的byte数组,没有必要一定要凭借单一使用的InputStreamResource。
ResourceLoader
ResourceLoader被用于实现可以返回Resource实例的对象。
public interface ResourceLoader {
Resource getResource(String location);
}
ps:所有的AoolicationContext都实现了ResourceLoaderAware接口,因此所有的ApplicationContext都可以被用来获取Resoure实例。
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
note:ctx为ClassPathXmlApplicationContext实例。
note:返回的Resource是ClassPathResource。
ps:当在特定的ApplicationContext中调用getResource(),并且指定的位置路径并没有指定特定的前缀时,返回的Resource的类型对应ApplicationContext的类型。
ResourceLoaderAware接口
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
ps:当实现ResourceLoaderAware的类作为bean部署进应用时,ApplicationContext将会将自身作为ResourceLoader注入。
ps:实现了ResourceLoader的类可以直接利用注入的ResourceLoaderAware加载资源,不过通常情况下会选择使用一个专门的ResourceLoader接口。
ps:可是通过@Autowired直接注入,或者通过setter与构造器自动注入。
作为依赖的资源
如果bean自身可以通过某些动态过程决定并提供资源路径,这对于使用ResourceLoader接口将会有意义。
<bean id="myBean" class="...">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
note:将myBean的Resource类型的template属性注入"some/resource/path/myTemplate.txt"资源。
ps:将注入属性变得简单的原因是ApplicationContext注册并使用一个特定的bean,PropertyEditor。
ps:PropertyEditor将Spring路径转变为Resource对象。
ps:注入时使用的ResourceLoader即ApplicationContext。