Resource简介
在Spring内部,针对于资源文件有一个统一的接口
Resource
表示。其主要实现类有
ClassPathResource
、
FileSystemResource
、
UrlResource
、
ByteArrayResource
、
ServletContextResource
和
InputStreamResource
。Resource接口中主要定义有以下方法:
exists
():用于判断对应的
资源是否真的存在
。
isReadable
():用于判断对应资源的
内容是否可读
。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。
isOpen
():用于判断
当前资源是否代表一个已打开的输入流
,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。
getURL
():返回
当前资源对应的URL
。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。
getFile
():返回
当前资源对应的File
。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。
getInputStream():获取当前
资源代表的输入流
。除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。
ClassPathResource可用来获取类路径下的资源文件
。假设我们有一个资源文件test.txt在类路径下,就可以通过给定对应资源文件在类路径下的路径path来获取它,new ClassPathResource(“test.txt”)。
FileSystemResource
可用来获取
文件系统里面的资源
。可以通过对应资源文件的文件路径来构建一个FileSystemResource。FileSystemResource还可以往对应的资源文件里面写内容,当然前提是当前资源文件是可写的,这可以通过其isWritable()方法来判断。FileSystemResource对外开放对应资源文件的输出流,可以通过getOutputStream()方法获取到。
UrlResource
可用来代表
URL对应的资源
,对URL做一个简单的封装。通过给定一个URL地址,就能构建一个UrlResource。
ByteArrayResource
是针对于
字节数组封装的资源
,它的构建需要一个字节数组。
ServletContextResource
是针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。ServletContextResource持有一个ServletContext的引用,其底层是通过ServletContext的getResource()方法和getResourceAsStream()方法来获取资源的。
InputStreamResource
是针对于输入流封装的资源,它的构建需要一个输入流。
public
class
ResourceTest {
* ClassPathResource可以用来获取类路径下的资源
*
@throws
IOException
@Test
public
void
testClassPath()
throws
IOException {
Resource resource
=
new
ClassPathResource("test.txt"
);
String fileName
=
resource.getFilename();
System.out.println(fileName);
//
resource.getFile();
//
获取资源对应的文件
//
resource.getURL();
//
获取资源对应的URL
if
(resource.isReadable()) {
//
每次都会打开一个新的流
InputStream is =
resource.getInputStream();
this
.printContent(is);
* FileSystemResource可以用来获取文件系统里面的资源,对于FileSystemResource而言我们
* 可以获取到其对应的输出流。
*
@throws
IOException
@Test
public
void
testFileSystem()
throws
IOException {
FileSystemResource resource
=
new
FileSystemResource("D:\\test.txt"
);
if
(resource.isReadable()) {
//
FileInputStream
printContent(resource.getInputStream());
if
(resource.isWritable()) {
//
每次都会获取到一个新的输出流
OutputStream os =
resource.getOutputStream();
BufferedWriter bw
=
new
BufferedWriter(
new
OutputStreamWriter(os, "UTF-8"
));
bw.write(
"你好,中国!"
);
bw.flush();
if
(os !=
null
) {
os.close();
if
(bw !=
null
) {
bw.close();
* 针对于URL进行封装的Resource,可用来从URL获取资源内容
*
@throws
Exception
@Test
public
void
testURL()
throws
Exception {
UrlResource resource
=
new
UrlResource("http://www.google.com.hk"
);
if
(resource.isReadable()) {
//
URLConnection对应的getInputStream()。
printContent(resource.getInputStream());
* 针对于字节数组封装的Resource,用来从字节数组获取资源内容
*
@throws
IOException
@Test
public
void
testByteArray()
throws
IOException {
ByteArrayResource resource
=
new
ByteArrayResource("Hello"
.getBytes());
//
ByteArrayInputStream()
printContent(resource.getInputStream());
* 针对于输入流的Resource,其getInputStream()方法只能被调用一次。
*
@throws
Exception
@Test
public
void
testInputStream()
throws
Exception {
InputStream is
=
new
FileInputStream("D:\\test.txt"
);
InputStreamResource resource
=
new
InputStreamResource(is);
//
对于InputStreamResource而言,其getInputStream()方法只能调用一次,继续调用将抛出异常。
InputStream target = resource.getInputStream();
//
返回的就是构件时的那个InputStream
//
is将在printContent方法里面进行关闭
printContent(target);
* 输出输入流的内容
*
@param
is
*
@throws
IOException
private
void
printContent(InputStream is)
throws
IOException {
BufferedReader br
=
new
BufferedReader(
new
InputStreamReader(is));
String line;
while
((line=br.readLine()) !=
null
) {
System.out.println(line);
if
(is !=
null
) {
is.close();
if
(br !=
null
) {
br.close();
通过ResourceLoader获取资源
在Spring里面还定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。它的实现类有很多,这里我们先挑一个DefaultResourceLoader来讲。DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。
@Test
public void testResourceLoader() {
ResourceLoader loader = new DefaultResourceLoader();
Resource resource = loader.getResource("http://www.google.com.hk");
System.out.println(resource instanceof UrlResource); //true
//注意这里前缀不能使用“classpath*:”,这样不能真正访问到对应的资源,exists()返回false
resource = loader.getResource("classpath:test.txt");
System.out.println(resource instanceof ClassPathResource); //true
resource = loader.getResource("test.txt");
System.out.println(resource instanceof ClassPathResource); //true
ApplicationContext接口也继承ResourceLoader接口,所以它的所有实现类都实现ResourceLoader接口,都可以用来获取Resource。
对于ClassPathXmlApplicationContext而言,它在获取Resource时继承的是它的父类DefaultResourceLoader的策略。
FileSystemXmlApplicationContext也继承了DefaultResourceLoader,但是它重写了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在获取资源文件时首先也是判断指定的location是否包含“classpath:”前缀,如果包含,则把location中“classpath:”前缀后的资源从类路径下获取出来,当做一个ClassPathResource;否则,继续尝试把location封装成一个URL,返回对应的UrlResource;如果还是失败,则把location指定位置的资源当做一个FileSystemResource进行返回。
在bean中获取Resource的方式
通过上面内容的介绍,我们知道,在bean中获取Resource主要有以下几种方式:
1.直接通过new各种类型的Resource来获取对应的Resource。
2.在bean里面获取到对应的ApplicationContext,再通过ApplicationContext的getResource(String path)方法获取对应的Resource。
3.直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。
4.通过依赖注入的方式把Resource注入到bean中。示例如下:
类ClassA:
public class ClassA {
//持有一个Resource属性
private Resource resource;
public void printContent() {
if (resource != null && resource.exists()) {
if (resource.isReadable()) {
InputStream is;
try {
is = resource.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line=br.readLine()) != null) {
System.out.println(line);
if (is != null) {
is.close();
if (br != null) {
br.close();
} catch (IOException e) {
e.printStackTrace();
public void setResource(Resource resource) {
this.resource = resource;
applicationContext.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="classA" class="com.xxx.ClassA">
<property name="resource">
<value>classpath:applicationContext.xml</value>
</property>
</bean>
</beans>
http://elim.iteye.com/blog/2016305
立志如山 静心求实