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):
java代碼:查看復制到剪貼板打印@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"); //驗證返回的是ClassPathResource 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。
java代碼:查看復制到剪貼板打印public interface ResourceLoaderAware { void setResourceLoader(ResourceLoader resourceLoader); }
讓我們看下測試代碼吧:
1) 首先準備測試Bean,我們的測試Bean還簡單只需實現ResourceLoaderAware接口,然后通過回調將ResourceLoader保存下來就可以了:
java代碼:查看復制到剪貼板打印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):
java代碼:查看復制到剪貼板打印 <bean class="cn.javass.spring.chapter4.bean.ResourceBean"/>
3)測試(cn.javass.spring.chapter4.ResoureLoaderAwareTest):
java代碼:查看復制到剪貼板打印@Test 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:
java代碼:查看復制到剪貼板打印package cn.javass.spring.chapter4.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):
java代碼:查看復制到剪貼板打印<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"/> </bean>
注意此處“resourceBean1”注入的路徑沒有前綴表示根據使用的ApplicationContext實現進行選擇Resource實現。
3)讓我們來看下測試代碼(cn.javass.spring.chapter4.ResourceInjectTest)吧:
java代碼:查看復制到剪貼板打印@Test public void test() { 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的支持,及如何使用更便利的資源加載方式。
原創內容 轉自請注明出處【http://sishuok.com/forum/blogPost/list/0/2457.html】
新聞熱點
疑難解答