ResourceLoader
ResourceLoader接口返回的是一个Resource 对象
Spring提供了两个ResourceLoader接口的实现
- DefaultResourceLoader
适用于所有环境,可以返回UrlResource,ClassPathResource
- ServletContextResourceLoader
适用于web环境,拥有DefaultResourceLoader的功能,另外还额外提供了获取ServletContextResource的支持
ResourceLoader在进行资源加载时需要使用前缀来指定,需要加载“classpath:path”则返回ClassPathResouce,“http://path”
和”file:path”则返回UrlResource,如果没有加载则需要根据上下文判断,DefaultResourceLoader默认是加载classpath
ResourceLoader.class
package org.springframework.core.io;
public abstract interface ResourceLoader
{
public static final String CLASSPATH_URL_PREFIX = "classpath:";
public abstract Resource getResource(String paramString);
public abstract ClassLoader getClassLoader();
}
DefaultResourceLoader.class
public Resource getResource(String location)
{
Assert.notNull(location, "Location must not be null");
if (location.startsWith("classpath:")) {
return new ClassPathResource(location.substring("classpath:".length()), getClassLoader());
}
try
{
URL url = new URL(location);
return new UrlResource(url);
}
catch (MalformedURLException ex) {
}
return getResourceByPath(location);
}
ResourceLoaderTest.java
package com.test;
import java.net.MalformedURLException;
import org.junit.Test;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
public class ResourceLoaderTest {
@Test
public void ResourceLoaderTest(){
ResourceLoader loader=new DefaultResourceLoader();
Resource resource;
//加载UrlResource
resource = loader.getResource("file:d:\\a.txt");//startwith file:
if(resource.exists()){
ResourceUtil.stream(resource);
}
resource=loader.getResource("http://www.baidu.com");//startwith http://
if(resource.exists()){
ResourceUtil.stream(resource);
}
//加载ClassPathResource
resource = loader.getResource("classpath:test.properties");//startwith classpath:
if(resource.exists()){
ResourceUtil.stream(resource);
}
//默认加载ClassPathResource
resource = loader.getResource("test.properties");
if(resource.exists()){
ResourceUtil.stream(resource);
}
}
}
ApplicationContext都实现了ResourceLoader接口
- ClassPathXmlApplicationContext:不指定前缀则返回ClassPathResource,否则根据前缀来返回Resource
- FileSystemXmlApplicationContext:不指定前缀则返回FileSystemResource,否则根据前缀来返回Resource
- WebApplicationContext:不指定前缀则返回ServletContextResource,否则根据前缀来返回Resource
- 其他:根据当前上下文来返回Resource,,否则根据前缀来返回Resource
ApplicationContextResourceTest .java
package com.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
public class ApplicationContextResourceTest {
@Test
public void ApplicationContextResourceTest(){
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext();
//默认返回ClassPathResouce
Resource resource=context.getResource("applicationContextParent.xml");
if(resource.exists()){
ResourceUtil.stream(resource);
}
//根据前缀返回UrlResource
Resource resource=c2.getResource("http://www.baidu.com");
if(resource.exists()){
ResourceUtil.stream(resource);
}
}
}
ResourceLoaderAware(回调ResourceLoader)
ResourceLoaderAware是一个标记接口,通过ApplicationContext上下文注入ResourceLoader
定义一个Bean实现ResourceLoaderAware接口
ResourceBean .java
package com.resource;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
public class ResourceBean implements ResourceLoaderAware{
private ResourceLoader loader;
@Override
public void setResourceLoader(ResourceLoader loader) {
this.loader= loader;
}
public ResourceLoader getLoader() {
return loader;
}
}
简单配置Bean
<bean id="resourceBean" class="com.resource.ResourceBean">
</bean>
测试类
ResourceLoaderAwareTest .java
package com.test;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ResourceLoader;
import com.resource.ResourceBean;
public class ResourceLoaderAwareTest {
@Test
public void ResourceLoaderAwareTest(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextResource.xml");
ResourceBean resourceBean=context.getBean("resourceBean",ResourceBean.class);
ResourceLoader loader=resourceBean.getLoader();
//ApplicationContext是一个ResourceLoader
Assert.assertTrue(loader instanceof ApplicationContext);
}
}
注入Resource
回调或者注入ResourceLoader,然后在通过ResourceLoader来加载需要的资源,是否对只需要加载固定资源的时候,显得麻烦。
Spring提供了一个PropertyEditor“ResourceEditor”用于在注入的字符串和Resource之间进行转换。因此可以使用注入方式注入Resource。
ResourceEditor使用ApplicationContext注入的路径字符串获取相应的Resource。
定义一个Bean
ResourceBean .java
package com.resource;
import org.springframework.core.io.Resource;
public class ResourceBean {
private Resource resource;
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
}
配置文件
<bean id="resourceBean1" class="com.resource.ResourceBean">
<property name="resource" value="applicationContextResource.xml"/>
</bean>
<bean id="resourceBean2" class="com.resource.ResourceBean">
<property name="resource" value="classpath:applicationContextResource.xml"/>
</bean>
注意此处“resourceBean1”没有指定前缀所以根据使用的ApplicationContext的实现(ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、WebApplicationContext等)来选着Resource的实现
测试类
ResourceTest .java
package com.test;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import com.resource.ResourceBean;
public class ResourceTest {
@Test
public void ResourceTest(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextResource.xml");
ResourceBean resourceBean1=context.getBean("resourceBean1",ResourceBean.class);
ResourceBean resourceBean2=context.getBean("resourceBean2",ResourceBean.class);
if(resourceBean1.getResource().exists()){
ResourceUtil.stream(resourceBean1.getResource());
}
Assert.assertTrue(resourceBean1.getResource() instanceof ClassPathResource);
Assert.assertTrue(resourceBean2.getResource() instanceof ClassPathResource);
}
}