8.3.3 使用Resource作为属性

8.3.3 使用Resource作为属性

前面介绍了Spring提供的资源访问策略,但这些依赖访问策略要么使用Resource实现类,要么使用ApplicationContext来获取资源。实际上,当应用程序中的Bean实例需要访问资源时, Spring有更好的解决方法:直接利用依赖注入.
归纳起来,如果Bean实例需要访问资源,则有如下两种解决方案

  1. 在代码中获取Resource实例。
  2. 使用依赖注入

对于第一种方式的资源访问,当程序获取Resource实例时,总需要提供Resource所在的位置,不管通过FileSystemResource创建实例,还是通过ClassPathResource创建实例,或者通过ApplicationContextgetResource()方法获取实例,都需要提供资源位置。这意味着:资源所在的物理位置将被耦合到代码中,如果资源位置发生改变,则必须改写程序。因此,通常建议采用第二种方法,让SpringBean实例依赖注入资源。

程序示例

1
2
3
4
5
6
7
8
9
10
11
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\Inject_Resource
└─src\
├─beans.xml
├─book.xml
├─lee\
│ └─SpringTest.java
└─org\
└─crazyit\
└─app\
└─service\
└─TestBean.java

看如下TestBean,它有一个Resource类型的res实例变量,程序为该实例变量提供了对应的setter方法,这就可以利用Spring的依赖注入了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package org.crazyit.app.service;

import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.core.io.Resource;

public class TestBean
{
private Resource resource;

// res的setter方法
public void setResource(Resource resource)
{
this.resource = resource;
}
public void parse() throws Exception
{
// 获取该资源的简单信息
System.out.println(resource.getFilename());
System.out.println(resource.getDescription());
// 创建基于SAX的dom4j的解析器
SAXReader reader = new SAXReader();
Document doc = reader.read(resource.getFile());
// 获取根元素
Element el = doc.getRootElement();
List l = el.elements();
// 遍历根元素的全部子元素
for (Iterator it = l.iterator(); it.hasNext();)
{
// 每个节点都是<书>节点
Element book = (Element) it.next();
List ll = book.elements();
// 遍历<书>节点的全部子节点
for (Iterator it2 = ll.iterator(); it2.hasNext();)
{
Element eee = (Element) it2.next();
System.out.println(eee.getText());
}
}
}
}

上面程序中定义了一个Resource类型的res属性,该属性需要接受Spring的依赖注入。除此之外,程序中的parse方法用于解析res资源所代表的XML文件。

beans.xml

在容器中配置该Bean,并为该Bean指定资源文件的位置。配置文件如下。

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="test" class="org.crazyit.app.service.TestBean"
p:resource="classpath:book.xml" />
</beans>

上面配置文件中的p:res="classpath:book.xml"属性配置了资源的位置,并使用了classpath:前缀,这指明让Spring从类加载路径下加载book.xml文件。
与前面类似的是,此处的前缀也可采用http:ftp:file:等,这些前缀将强制Spring采用对应的资源访问策略(也就是指定具体使用哪个Resource实现类);
如果不采用任何前缀,则Spring将采用与该ApplicationContext相同的资源访问策略来访问资源。

使用依赖注入资源的优点

采用依赖注入,允许动态配置资源文件位置,无须将资源文件位置写在代码中,当资源文件位置发生变化时,无须改写程序,直接修改配置文件即可。