• Resource接口,及资源


    Resource介绍

    编码的时候,除了代码本身,我们还需要对外部的资源进行处理。例如:URL资源、URI资源、File资源、ClassPath相关资源、服务器相关资源(VFS等)等等。

    而这些资源的处理是类似而繁琐的,如:打开资源、读取资源、关闭资源。

    所以Spring提供了一个专门的接口Resource 用于统一这些底层资源的访问。

    就是说,Spring的Resource接口代表底层外部资源,提供了对底层外部资源的一致性访问接口

    源码如下:

    public interface InputStreamSource {
        InputStream getInputStream() throws IOException;
    }
    public interface Resource extends InputStreamSource {
        boolean exists();
        boolean isReadable();
        boolean isOpen();
        URL getURL() throws IOException;
        URI getURI() throws IOException;
        File getFile() throws IOException;
        long contentLength() throws IOException;
        long lastModified() throws IOException;
        Resource createRelative(String relativePath) throws IOException;
        String getFilename();
        String getDescription();
    }

    Resource接口提供了足够的抽象,足够满足我们日常使用。而且提供了很多内置Resource实现:ByteArrayResource、InputStreamResource 、FileSystemResource 、UrlResource 、ClassPathResource、ServletContextResource、VfsResource等。

    ByteArrayResource代表byte[]数组资源,对于 getInputStream() 操作将返回一个ByteArrayInputStream。ByteArrayResource可多次读取数组资源,即 isOpen() 永远返回false。
    
    InputStreamResource代表java.io.InputStream字节流,对于getInputStream() 操作将直接返回该字节流,因此只能读取一次该字节流,即 isOpen() 永远返回true。
    
    FileSystemResource代表java.io.File资源,对于 getInputStream() 操作将返回底层文件的字节流,isOpen() 将永远返回false,从而表示可多次读取底层文件的字节流。
    ClassPathResource代表classpath路径的资源,将使用ClassLoader进行加载资源。classpath 资源存在于类路径中的文件系统中或jar包里,且 isOpen() 永远返回false,表示可多次读取资源。
    ClassPathResource加载资源替代了Class类和ClassLoader类的getResource(String name)和getResourceAsStream(String name)两个加载类路径资源方法,提供一致的访问方式。
    ClassPathResource提供了三个构造器:
      public ClassPathResource(String path):使用默认的ClassLoader加载“path”类路径资源;
      public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加载“path”类路径资源;
      -- 比如当前类路径是“cn.javass.spring.chapter4.ResourceTest”,而需要加载的资源路径是“cn/javass/spring/chapter4/test1.properties”,则将加载的资源在“cn/javass/spring/chapter4/test1.properties”;
      public ClassPathResource(String path, Class<?> clazz):使用指定的类加载“path”类路径资源,将加载相对于当前类的路径的资源;
      -- 比如当前类路径是“cn.javass.spring.chapter4.ResourceTest”,而需要加载的资源路径是“cn/javass/spring/chapter4/test1.properties”,则将加载的资源在“cn/javass/spring/chapter4/cn/javass/spring/chapter4/test1.properties”;
      -- 而如果需要 加载的资源路径为“test1.properties”,将加载的资源为“cn/javass/spring/chapter4/test1.properties”。
      -- 需要注意一定:资源查找顺序是先查找当前类路径的资源,再去查找jar包,而且,只要找到就会返回
      -- 如果是在jar包中的资源,需要使用getURL(),而不是getFile(),因为资源不是存在于File系统,而是存在于jar包中!!!
    UrlResource代表URL资源,用于简化URL资源访问。“isOpen”永远返回false,表示可多次读取资源。
    
    UrlResource一般支持如下资源访问:
        http:通过标准的http协议访问web资源,如new UrlResource(“http://地址”);
        ftp:通过ftp协议访问资源,如new UrlResource(“ftp://地址”);
        file:通过file协议访问本地文件系统资源,如new UrlResource(“file:d:/test.txt”);
    ServletContextResource代表web应用资源,用于简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作;
    VfsResource代表Jboss 虚拟文件系统资源。

    Resource访问

    ResourceLoader接口用于返回Resource对象;其实现可以看作是一个生产Resource的工厂类。

    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资源

    目前所有的ApplicationContext都实现了ResourceLoader,因此可以使用其来加载资源。

    ClassPathXmlApplicationContext:不指定前缀将返回默认的ClassPathResource资源,否则将根据前缀来加载资源;
    FileSystemXmlApplicationContext:不指定前缀将返回FileSystemResource,否则将根据前缀来加载资源;
    WebApplicationContext:不指定前缀将返回ServletContextResource,否则将根据前缀来加载资源;
    其他:不指定前缀根据当前上下文返回Resource实现,否则将根据前缀来加载资源。

    ResourceLoader

    ResourceLoaderAware是一个标记接口,用于通过ApplicationContext注入ResourceLoader。

    注入Resource

    通过注入来获取ResourceLoader,再来访问资源,很麻烦!!!

    Spring提供了ResourceEditor(这是一个PropertyEditor),用于在注入的字符串和Resource之间进行转换。

    因此可以使用注入方式注入Resource

    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;
        }
    }
    <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实现。

     Resource通配符路径

    Spring提供了一种更强大的Ant模式通配符匹配,能匹配一批资源。

    Ant路径通配符支持“?”、“*”、“**”,注意通配符匹配不包括目录分隔符“/”:
        “?”:匹配一个字符,如“config?.xml”将匹配“config1.xml”;
        “*”:匹配零个或多个字符串,如“cn/*/config.xml”将匹配“cn/javass/config.xml”,但不匹配匹配“cn/config.xml”;而“cn/config-*.xml”将匹配“cn/config-dao.xml”;
        “**”:匹配路径中的零个或多个目录,如“cn/**/config.xml”将匹配“cn /config.xml”,也匹配“cn/javass/spring/config.xml”;而“cn/javass/config-**.xml”将匹配“cn/javass/config-dao.xml”,即把“**”当做两个“*”处理。

    小结:

    ① Spring通过Resource接口统一访问外部资源,并提供了一堆实现类,可以分别访问File、classpath、URL、URI等等资源。

    ② Spring通过ResourceLoader接口获取Resource。

    ③ ApplicationContext都实现了ResourceLoader接口,所以可以直接加载资源!

    ④ 实现ResourceLoaderAware接口,可以注入ResourceLoader。

    ⑤ 注入Resource。

    ⑥ Resource通配符路径。

    声明:源自张开涛的Spring教程,稍作加工。

  • 相关阅读:
    Excel jar包冲突 java.lang.NoSuchFieldError: DEFAULT
    js中foreach有三种写法,你知道吗
    上期CTP
    Visual Status各个版本官网下载
    电脑重装环境配置
    vue父子页面传值
    MySQL该使用哪种CPU架构服务器?
    【沥血整理】灰度(二值)图像重构算法及其应用(morphological reconstruction)。
    【短道速滑九】仿halcon中gauss_filter小半径高斯模糊优化的实现
    AVX图像算法优化系列一: 初步接触AVX。
  • 原文地址:https://www.cnblogs.com/larryzeal/p/5523578.html
Copyright © 2020-2023  润新知