RainSun

好学而不勤问非真好学者

Spring的Resource接口与ResourceLoader接口

Resource

其中,最常用的有四个:

  1. ClassPathResource:通过 ClassPathResource 以类路径的方式进行访问;
  2. FileSystemResource:通过 FileSystemResource 以文件系统绝对路径的方式进行访问;
  3. ServletContextResource:通过 ServletContextResource 以相对于Web应用根目录的方式进行访问;
  4. UrlResource :通过java.net.URL来访问资源,当然它也支持File格式,如“file:”。

ClassPathResource

@Override
public InputStream getInputStream() throws IOException {
    InputStream is;
    if (this.clazz != null) {
        is = this.clazz.getResourceAsStream(this.path);
    }
    else if (this.classLoader != null) {
        is = this.classLoader.getResourceAsStream(this.path);
    }
    else {
        is = ClassLoader.getSystemResourceAsStream(this.path);
    }
    if (is == null) {
        throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
    }
    return is;
}

通过ClassLoader#getResourceAsStream(String);Class#getResourceAsStream(String)获得流信息

ClassLoader#getResourceAsStream(String)的目录为class
Class#getResourceAsStream(String)的目录为当前Class文件目录
TestResource.class.getClassLoader().getResourceAsStream("")
TestResource.class.getClassLoader().getResourceAsStream("/")
TestResource.class.getResourceAsStream("")
TestResource.class.getResourceAsStream("/")
输出
file:/E:/Workspaces/base_Java/target/classes/
null
file:/E:/Workspaces1/myProject/base_Java/target/classes/com/code/resource/
file:/E:/Workspaces1/myProject/base_Java/target/classes/

FileSystemResource

@Override
public InputStream getInputStream() throws IOException {
    return new FileInputStream(this.file);
}

通过创建FileInputStream输入流获得流信息

ServletContextResource

@Override
public InputStream getInputStream() throws IOException {
    InputStream is = this.servletContext.getResourceAsStream(this.path);
    if (is == null) {
        throw new FileNotFoundException("Could not open " + getDescription());
    }
    return is;
}

通过ServletContext#getResourceAsStream返回资源文件的读取字节流

在web工程中,我们一般来说,是不能采取类加载器读取webRoot(webapp目录下)目录下配置文件的通过SevletContext#getResourceAsStream(“/imgs/test.properties”)获得输入流或通过SevletContext#getRealPath(“/imgs/Sunset.jpg”)获得绝对路径

UrlResource

@Override
public InputStream getInputStream() throws IOException {
    URLConnection con = this.url.openConnection();
    ResourceUtils.useCachesIfNecessary(con);
    try {
        return con.getInputStream();
    }
    catch (IOException ex) {
        // Close the HTTP connection (if applicable).
        if (con instanceof HttpURLConnection) {
            ((HttpURLConnection) con).disconnect();
        }
        throw ex;
    }
}

UrlResource 封装了java.net.URL,它能够被用来访问任何通过URL可以获得的对象,例如:文件、HTTP对象、FTP对象等。

ResourceLoader

类图结构

这里写图片描述

DefaultResourceLoader

@Override
public Resource getResource(String location) {
    Assert.notNull(location, "Location must not be null");

    for (ProtocolResolver protocolResolver : this.protocolResolvers) {
        Resource resource = protocolResolver.resolve(location, this);
        if (resource != null) {
            return resource;
        }
    }

    if (location.startsWith("/")) {
        return getResourceByPath(location);
    }
    else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
        return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
    }
    else {
        try {
            // Try to parse the location as a URL...
            URL url = new URL(location);
            return new UrlResource(url);
        }
        catch (MalformedURLException ex) {
            // No URL -> resolve as resource path.
            return getResourceByPath(location);
        }
    }
}

在Spring里面还定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。DefaultResourceLoader在获取Resource时:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。

PathMatchingResourcePatternResolver
解决路径下有一个或多个资源文件,源路径可能是一个简单的路径或者可能含有特殊的{classpath*:}前缀和或Ant-style正则表达式(请看 org.springframework.util.AntPathMatcher类

Resource[] re = pmrp.getResources("com/spring/**/*.class");
    for(int i = 0;i < re.length;i++) {
        System.out.println(re[i]);
}
输出class/com/spring下的所有文件:
file [E:\Workspaces\base_Java\target\classes\com\spring\springbean\SpringBeanTest.class]
file [E:\Workspaces\base_Java\target\classes\com\spring\springbean\SpringBeanTest2.class]
file [E:\Workspaces\base_Java\target\classes\com\spring\springbean\SpringBeanTest3.class]

Ant-style正则表达式:
? 匹配任何单字符
* 匹配0或者任意数量的字符
** 匹配0或者更多的目录

例如:
/app/*.x 匹配(Matches)所有在app路径下的.x文件
/app/p?ttern 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern
/**/example 匹配(Matches) /app/example, /app/foo/example, 和 /example
/app/**/dir/file. 匹配(Matches) /app/dir/file.jsp, > /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java
/**/*.jsp 匹配(Matches)任何的.jsp 文件

阅读更多
个人分类: spring
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Spring的Resource接口与ResourceLoader接口

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭