zoukankan      html  css  js  c++  java
  • 资源访问

    ClassPathXmlApplicationContext是Spring应用上下文的其中一种实现,它的实例通常可以这样创建:

    1 var context = new ClassPathXmlApplicationContext("resources\\app-config.xml"))

    可以看到ClassPathXmlApplicationContext拿到文件路径 resources\app-config.xml 之后即能给基于类路径加载配置文件完成Bean的创建,事情出奇地简单!可在简单的背后,却深藏着Spring应用上下文不为人知的努力。资源访问就是其中一件。

    众所周知,Spring应用上下文是基于ApplicationContext接口进行实现的。而ApplicationContext接口又继承了ResourceLoader接口,能够加载诸如XML配置文件之类的资源。自然而然的,实现了ApplicationContext接口的Spring应用上下文也就具有加载XML配置文件这种资源的能力。ResourceLoader接口定义如下:

    1 public interface ResourceLoader {
    2     Resource getResource(String location);
    3 }

    该接口只定义了 Resource getResource(String location) 方法,接受一个字符串类型的资源路径之后即能创建一个Resource类型的对象返回给调用者。而Resource是Spring定义的一个关于资源的接口,具有以下几种常见的资源访问方法:
    1. InputStream getInputStream() :打开资源之后创建和返回java.io.InputStream类型的对象,以供调用者以数据流的方式读取资源。注意:每次调用该方法都会创建和返回一个新的InputStream类型的对象。用完之后记得把它关掉,以免造成内存泄漏。
    2. File getFile() :获取java.io.File类型的对象,能够提供诸如文件位置,文件大小,文件读写权限之类的信息。
    3. String getFilename() :获取资源的文件名。
    4. String getDescription() :获取资源的描述信息,通常含有资源的完整路径。
    5. boolean exists() :检查资源是否存在。

    Resource接口具有多种实现,常见的有以下几种:
    1.UrlResource:这种实现只是简单封装一下Java基础类库里的java.net.URL。因此,URL能做的事,UrlResource同样也能。
    2.ClassPathResource:基于类路径加载资源。
    3.FileSystemResource:基于应用程序当前工作目录加载资源。
    4.ServletContextResource:基于Web应用程序根目录加载资源。非常明显,这种实现是与Web应用程序挂钩的。

    可以看到常见的Resource实现共有四种。不同的Spring应用上下文实现ResourceLoader接口时,创建的资源类型是不同的。对应如下:
    1.ClassPathXmlApplicationContext创建的是ClassPathResource类型的资源。
    2.FileSystemXmlApplicationContext创建的是FileSystemResource类型的资源。
    3.XmlWebApplicationContext创建的是ServletContextResource类型的资源。

    于是我们知道了,Spring应用上下文加载XML配置文件的过程是这样的:Spring应用上下文完成实例的创建之后,将会调用ResourceLoader接口创建Resource类型的对象进行XML配置文件的加载。如果Spring应用上下文是ClassPathXmlApplicationContext类型的,创建的则是ClassPathResource类型的资源,能够基于类路径加载XML配置文件;如果Spring应用上下文是FileSystemXmlApplicationContext类型的,创建的则是FileSystemResource类型的资源,能够基于应用程序当前工作目录加载XML配置文件;如果Spring应用上下文是XmlWebApplicationContext类型的,创建的则是ServletContextResource类型的资源,能够基于Web应用程序根目录加载XML配置文件。

    额外让人惊喜的是,我们还能这样指定文件路径进行Spring应用上下文的创建:

    1 var context = new ClassPathXmlApplicationContext(
    2         "file:out\\production\\music-player\\resources\\app-config.xml")

    可以看到,我们传给Spring应用上下文的文件路径不但变了,而且新带了个神秘的 file: 前缀。

    这是怎么回事呢?

    原来,ResourceLoader创建资源时,会先看看文件路径是否带有前缀。如果没带前缀,就会创建前文提到的与Spring应用上下文对应的资源;如果有带前缀,就会根据不同的前缀创建不同的资源。这意味着我们可以通过前缀改变资源的类型,从而改变Spring应用上下文加载XML配置文件的方式。

    目前支持的前缀有 classpath:  file:  http:  ftp: 。如果指定 classpath: 前缀,则会创建ClassPathResource,基于类路径加载资源。如果指定 file:  http:  ftp: 前缀,则会创建UrlResource,以java.net.URL的方式加载资源。这意味着如果指定 file: 前缀,则可在前缀后面指定资源的相对路径或绝对路径进行资源的加载;如果指定 http:  ftp: 前缀,则可在前缀后面指定网络资源的位置进行网络资源的加载。

    可以看到前缀的引入让资源的加载变得非常灵活,我们随时都能通过添加前缀改变资源的加载方式。那么,Spring应用上下文是否也支持以通配符的方式进行XML配置文件的加载,让事情变得更加方便呢?

    答案是肯定的,Spring应用上下文支持Ant风格的通配符。实际上,Spring应用上下文调用ResourceLoader加载资源之前,会先解析通配符找出所有匹配的文件路径。之后,Spring应用上下文以匹配的文件路径为参数循环调用ResourceLoader完成资源的加载。以下是Spring应用上下文支持的Ant风格的通配符:

    通配符

    用途

    示例

    ?

    匹配任意一个字符

    通配符路径resources\app-confi?.xml能够匹配这些路径:
    1.resources\app-confia.xml
    2.resources\app-confib.xml
    3.resources\app-confic.xml

    *

    匹配零或多个字符

    通配符路径resources\*.xml能够匹配这些路径:
    1.resources\a.xml
    2.resources\b.xml
    3.resources\c.xml

    **

    匹配零或多个目录

    通配符路径resources\**\app-config.xml能够匹配这些路径:
    1.resources\app-config.xml
    2.resources\aa\app-config.xml
    3.resources\bb\app-config.xml

    至此,关于Spring应用上下文是怎样加载XML配置文件的,我们已经弄清楚了。问题在于,XML配置文件是资源,PNG格式的图片是资源,Word文档同样也是资源。如果我们想访问的是诸如PNG格式的图片之类的资源,又该怎么做呢?

    总体而言,访问这样的资源有两种方式:一种是自己手动创建资源对象(比如UrlResource,ClassPathResource,FileSystemResource,ServletContextResource,等等),而后使用资源对象访问资源;一种是获取存在Spring应用上下文里的ResourceLoader之后,使用ResourceLoader加载资源,访问资源。第一种方式只需创建资源对象,调用资源对象的方法访问资源即可,这里不作介绍;对于第二种方式,Spring提供了这些支持:
    1.ApplicationContextAware接口:实现ApplicationContextAware接口之后,我们的Bean就能拿到ApplicationContext。ApplicationContext是继承了ResourceLoader接口的。因此,能够调用ApplicationContext的getResource方法加载资源,访问资源。
    2.自动装配ApplicationContext:通过自动装配把ApplicationContext装配到我们的Bean里,而后调用ApplicationContext的getResource方法加载资源,访问资源。
    3.ResourceLoaderAware接口:实现ResourceLoaderAware接口之后,我们的Bean能够拿到ResourceLoader。之后,只要调用ResourceLoader的getResource方法就能加载资源,访问资源。ResourceLoaderAware接口定义如下:

    public interface ResourceLoaderAware {
        void setResourceLoader(ResourceLoader resourceLoader);
    }

    4.自动装配ResourceLoader:通过自动装配把ResourceLoader装配到我们的Bean里,而后调用ResourceLoader的getResource方法加载资源,访问资源。

    至此,关于资源访问的介绍告一段落。下一章,我们将会开始丰富Bean的配置。欢迎大家继续阅读,谢谢大家!

    返回目录    下载代码

  • 相关阅读:
    洛谷—— P3353 在你窗外闪耀的星星
    洛谷—— P1238 走迷宫
    洛谷—— P1262 间谍网络
    9.8——模拟赛
    洛谷—— P1189 SEARCH
    算法
    May 22nd 2017 Week 21st Monday
    May 21st 2017 Week 21st Sunday
    May 20th 2017 Week 20th Saturday
    May 19th 2017 Week 20th Friday
  • 原文地址:https://www.cnblogs.com/evanlin/p/15800044.html
Copyright © 2011-2022 走看看