天天看点

Spring- Resource ——跟我学spring3

<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):

&lt;bean class="cn.javass.spring.chapter4.bean.resourcebean"/&gt;  

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):

&lt;bean id="resourcebean1" class="cn.javass.spring.chapter4.bean.resourcebean3"&gt;  

   &lt;property name="resource" value="cn/javass/spring/chapter4/test1.properties"/&gt;  

&lt;/bean&gt;  

&lt;bean id="resourcebean2" class="cn.javass.spring.chapter4.bean.resourcebean3"&gt;  

&lt;property name="resource"  

value="classpath:cn/javass/spring/chapter4/test1.properties"/&gt;  

       注意此处“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的支持,及如何使用更便利的资源加载方式。