Resource接口,及资源

摘要:
当Resource引入编码时,除了代码本身,我们还需要处理外部资源。ByteArrayResource表示byte[]数组资源。对于getInputStream()操作,将返回ByteArrayInputStream。ClassPathResource表示类路径的资源。ClassLoader将用于加载资源。ClassPathResource加载资源替换了Class和ClassLoader类的getResource和getResourceAsStream方法来加载类路径资源,从而提供了一致的访问方法。UrlResource表示URL资源,用于简化URL资源访问。“IsOpen”始终返回false,表示可以多次读取资源。Resource访问ResourceLoader接口以返回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教程,稍作加工。

免责声明:文章转载自《Resource接口,及资源》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OpenFeign远程调用原理异步任务分发模块Celery下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Postman介绍(2)

一、使用Postman的模拟服务模拟(mock)后端 在整个开发过程中,前端或后端的延迟可能会阻碍相关团队有效地完成工作。一些后端的API工程师已经开始使用Postman去测试后端endpoint,而不依赖于前端UI来模拟API请求。 现在,Postman开发了一种新的模拟服务,使团队能够模拟后端服务器。前端开发人员可以模拟Postman collecti...

03生成微博授权的url接口(再也没有你了)

生成微博授权url接口 (再也没有你了) 相信朋友们对微博开放平台的使用以及有了进一步的了解,那么接下来我们来看看怎么使用微博开放平台: 1.创建apps/oauth模块进行oauth认证 '''1.1在apps文件夹下新建应用: oauth''' cd syl/apps python ../manage.py startapp oauth # 切换到a...

Mybatis框架的输出映射类型

  Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。 resultType(输出类型) 1.输出简单类型 (1)我们在UserMapper接口中定义查找数据库中用户总人数的方法:   public Integer findUserCount(); (2)在UserMapper.xm...

交换机端口安全Port-Security超级详解

一、Port-Security概述   在部署园区网的时候,对于交换机,我们往往有如下几种特殊的需求: 限制交换机每个端口下接入主机的数量(MAC地址数量) 限定交换机端口下所连接的主机(根据IP或MAC地址进行过滤) 当出现违例时间的时候能够检测到,并可采取惩罚措施   上述需求,可通过交换机的Port-Security功能来实现:  ...

Repository总结

Repository有两种实现思想1.自由式。领域层(DomainModel和DomainService)需要什么样的数据,都问Repository拿,Repository根据领域层的需要,增加许多方法。2.固定式。Repository只提供有限的几个接口,其中查询数据只提供FindById、GetAll几种方法。 注意,固定式、特别是泛型的固定式(泛型的...

接口测试笔记

1.2 一..接口测试:通过相应的工具或者人工对某一个接口的工作状态进行测试的过程 二..接口测试点: 1.测试接口正确性:保证接口地址与请求方法是正确的 2.测试接口的安全性:有一些接口不能直接暴露,我们需要对它进行炎症之后才可以去调用 3.测试接口的性能:例如:我们需要考虑某一个接口在N多个用户访问的时候工作的压力 4.测试接口的数据:保证接口返回的数...