Resources
Spring定义用于处理位于classpath和相对路径下的资源的一系列接口方法。
- The Resource Interface
- Built-in Resource Implementations
- The ResourceLoader
- The ResourceLoaderAware interface
- Resources as Dependencies
1.1. The Resource Interface
Spring的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();
}
Resource接口继承了InputStreamSource接口:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Resource 接口比较重要的方法:
getInputStream(): 定义并打开当前资源,返回从资源读取的输入流。每个调用者打开的都是独立的资源,调用者需要手动关闭输入流。
exists(): 当前资源是否真实存在。
isOpen():当前资源是否已经被打开,如果返回true则只能被打开一次并且需要手动关闭以防资源泄漏。大多数情况下实现接口返回的是false;
getDescription(): 返回资源的描述,一般返回的是资源名称或者资源的绝对路径。
2.1. Built-in Resource Implementations
Spring 包含以下Resource接口的实现类
UrlResource
ClassPathResource
FileSystemResource
ServletContextResource
InputStreamResource
ByteArrayResource
2.1.1. UrlResource
UrlResource可以用于访问URL或者HTTP,FTP类似的资源。
http:通过标准的http协议访问web资源,如new UrlResource(“http://地址”);
ftp:通过ftp协议访问资源,如new UrlResource(“ftp://地址”);
file:通过file协议访问本地文件系统资源,如new UrlResource(“file:d:/test.txt”)
UrlResource ur = new UrlResource("file:web.xml")
2.1.2. ClassPathResource
ClassPathResource代表classpath下的资源,主要是用ClassLoader加载资源。
ClassPathResource提供了三个构造器:
public ClassPathResource(String path):使用默认的ClassLoader加载“path”类路径资源;
public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加载“path”类路径资源;
public ClassPathResource(String path, Class<?> clazz):使用指定的类加载“path”类路径资源,将加载相对于当前类的路径的资源;
2.1.3. FileSystemResource
代表java.io.File资源,对于getInputStream操作将返回底层文件的字节流,isOpen将永远返回false,从而表示可多次读取底层文件的字节流。
public static void Test_FileSystemResource() {
File file = new File("d:/test.txt");
Resource resource = new FileSystemResource(file);
if (resource.exists()) {
dumpStream(resource);
}
Assert.isTrue(!resource.isOpen());
}
2.314. ServletContextResource
访问Web Context下相对路径下的资源,入参的资源位置是相对于Web应用根路径的位置(工程文件夹下,WEB-INF所在的那级文件夹)。用于简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作。
使用ServletContextResource无需关心资源是否被解压缩出来,或者直接存放在JAR文件中,都可以通过Servlet容器访问。
入参需要ServletContext和字符串类型:
public class ResourceTest {
ServletContextResource resource = new ServletContextResource(servletContext,"spring.xml");
}
2.1.5. InputStreamResource
代表java.io.InputStream字节流,对于getInputStream操作将直接返回该字节流,因此只能读取一次该字节流,即isOpen永远返回true(其他Resource大都为false可以多次读取)
只有当没有合适的Resource实现时,才考虑使用InputStreamResource。一般考虑使用ByteArrayResource
public static void Test_InputStreamResource() {
ByteArrayInputStream bis = new ByteArrayInputStream(
"Hello Spring!".getBytes());
Resource resource = new InputStreamResource(bis);
if (resource.exists()) {
dumpStream(resource);
}
Assert.isTrue(resource.isOpen());
}
2.1.6. ByteArrayResource
可多次读取数组资源,即isOpen()永远返回false
入参需要byte[] 字节数组类型
public static void Test_ByteArrayResource() {
Resource resource = new ByteArrayResource("Hello!Spring!你好!".getBytes());
if (resource.exists()) {
dumpStream(resource);
}
}
private static void dumpStream(Resource resource) {
InputStream is = null;
try {
//1.获取文件资源
is = resource.getInputStream();
//2.读取资源
byte[] descBytes = new byte[is.available()];
is.read(descBytes);
System.out.println(new String(descBytes));
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
//3.关闭资源
is.close();
} catch (IOException e) {
}
}
}
ByteArrayResource因为入参可以是byte[]类型,所以用途比较广泛,可以把从网络或者本地资源都转换为byte[]类型,然后用ByteArrayResource转化为资源。
2.2. The ResourceLoader
ResourceLoader接口用于定义返回任何资源示例的加载器类,接口定义如下:
public interface ResourceLoader {
Resource getResource(String location);
}
Spring的应用上下文类都实现了ResourceLoader接口,因此应用上下文可以记载资源实例,比如
ClassPathXmlApplicationContext:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
同样的,对于FileSystemXmlApplicationContext上下文类,返回的是FileSystemResource,WebApplicationContext返回的是WebApplicationContext。
不同的应用上下文都可以类似的返回自己匹配的资源类示例。
另一方面,可以强制使用前缀来生成特定类型的资源实例,比如‘classpath:’:
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
同样的,可以使用不同的前缀来生成不同的资源实例:
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
The following table summarizes the strategy for converting String objects to Resource objects:
2.3. The ResourceLoaderAware interface
ResourceLoaderAware定义用于提供ResourceLoader引用的接口,接口定义如下:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
当一个类实现了ResourceLoaderAware接口并且作为一个Bean部署到Spring应用中,Spring的application context会调用setResourceLoader方法将ResourceLoader提供给它(每一个 application context都实现了ResourceLoader接口)。
最好使用单独的类来实现ApplicationContextAware接口并加载需要的资源。
2.4. Resources as Dependencies
https://www.cnblogs.com/alsf/p/8060095.html
2.5. Application Contexts and Resource Paths
使用资源创建应用上下文(application context)。