<a href="http://sishuok.com/forum/blogpost/list/2457.html">【第四章】 资源 之 4.3 访问resource ——跟我学spring3 </a>
resourceloader接口用于返回resource对象;其实现可以看作是一个生产resource的工厂类。
java代码:
public interface resourceloader {
resource getresource(string location);
classloader getclassloader();
}
getresource接口用于根据提供的location参数返回相应的resource对象;而getclassloader则返回加载这些resource的classloader。
spring提供了一个适用于所有环境的defaultresourceloader实现,可以返回classpathresource、urlresource;还提供一个用于web环境的servletcontextresourceloader,它继承了defaultresourceloader的所有功能,又额外提供了获取servletcontextresource的支持。
resourceloader在进行加载资源时需要使用前缀来指定需要加载:“classpath:path”表示返回classpathresource,“http://path”和“file:path”表示返回urlresource资源,如果不加前缀则需要根据当前上下文来决定,defaultresourceloader默认实现可以加载classpath资源,如代码所示(cn.javass.spring.chapter4.resourceloadertest):
@test
public void testresourceload() {
resourceloader loader = new defaultresourceloader();
resource resource = loader.getresource("classpath:cn/javass/spring/chapter4/test1.txt");
//验证返回的是classpathresource
assert.assertequals(classpathresource.class, resource.getclass());
resource resource2 = loader.getresource("file:cn/javass/spring/chapter4/test1.txt");
assert.assertequals(urlresource.class, resource2.getclass());
resource resource3 = loader.getresource("cn/javass/spring/chapter4/test1.txt");
//验证返默认可以加载classpathresource
assert.asserttrue(resource3 instanceof classpathresource);
对于目前所有applicationcontext都实现了resourceloader,因此可以使用其来加载资源。
classpathxmlapplicationcontext:不指定前缀将返回默认的classpathresource资源,否则将根据前缀来加载资源;
filesystemxmlapplicationcontext:不指定前缀将返回filesystemresource,否则将根据前缀来加载资源;
webapplicationcontext:不指定前缀将返回servletcontextresource,否则将根据前缀来加载资源;
其他:不指定前缀根据当前上下文返回resource实现,否则将根据前缀来加载资源。
resourceloaderaware是一个标记接口,用于通过applicationcontext上下文注入resourceloader。
public interface resourceloaderaware {
void setresourceloader(resourceloader resourceloader);
让我们看下测试代码吧:
1) 首先准备测试bean,我们的测试bean还简单只需实现resourceloaderaware接口,然后通过回调将resourceloader保存下来就可以了:
package cn.javass.spring.chapter4.bean;
import org.springframework.context.resourceloaderaware;
import org.springframework.core.io.resourceloader;
public class resourcebean implements resourceloaderaware {
private resourceloader resourceloader;
@override
public void setresourceloader(resourceloader resourceloader) {
this.resourceloader = resourceloader;
}
public resourceloader getresourceloader() {
return resourceloader;
2) 配置bean定义(chapter4/resourceloaderaware.xml):
<bean class="cn.javass.spring.chapter4.bean.resourcebean"/>
3)测试(cn.javass.spring.chapter4.resoureloaderawaretest):
public void test() {
applicationcontext ctx = new classpathxmlapplicationcontext("chapter4/resourceloaderaware.xml");
resourcebean resourcebean = ctx.getbean(resourcebean.class);
resourceloader loader = resourcebean.getresourceloader();
assert.asserttrue(loader instanceof applicationcontext);
注意此处“loader instanceof applicationcontext”,说明了applicationcontext就是个resoureloader。
由于上述实现回调接口注入resourceloader的方式属于侵入式,所以不推荐上述方法,可以采用更好的自动注入方式,如“bytype”和“constructor”,此处就不演示了。
通过回调或注入方式注入“resourceloader”,然后再通过“resourceloader”再来加载需要的资源对于只需要加载某个固定的资源是不是很麻烦,有没有更好的方法类似于前边实例中注入“java.io.file”类似方式呢?
spring提供了一个propertyeditor “resourceeditor”用于在注入的字符串和resource之间进行转换。因此可以使用注入方式注入resource。
resourceeditor完全使用applicationcontext根据注入的路径字符串获取相应的resource,说白了还是自己做还是容器帮你做的问题。
接下让我们看下示例:
1)准备bean:
import org.springframework.core.io.resource;
public class resourcebean3 {
private resource resource;
public resource getresource() {
return resource;
public void setresource(resource resource) {
this.resource = resource;
2)准备配置文件(chapter4/ resourceinject.xml):
<bean id="resourcebean1" class="cn.javass.spring.chapter4.bean.resourcebean3">
<property name="resource" value="cn/javass/spring/chapter4/test1.properties"/>
</bean>
<bean id="resourcebean2" class="cn.javass.spring.chapter4.bean.resourcebean3">
<property name="resource"
value="classpath:cn/javass/spring/chapter4/test1.properties"/>
注意此处“resourcebean1”注入的路径没有前缀表示根据使用的applicationcontext实现进行选择resource实现。
3)让我们来看下测试代码(cn.javass.spring.chapter4.resourceinjecttest)吧:
applicationcontext ctx = new classpathxmlapplicationcontext("chapter4/resourceinject.xml");
resourcebean3 resourcebean1 = ctx.getbean("resourcebean1", resourcebean3.class);
resourcebean3 resourcebean2 = ctx.getbean("resourcebean2", resourcebean3.class);
assert.asserttrue(resourcebean1.getresource() instanceof classpathresource);
assert.asserttrue(resourcebean2.getresource() instanceof classpathresource);
接下来一节让我们深入applicationcontext对各种resource的支持,及如何使用更便利的资源加载方式。