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 {2Resource 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的配置 。欢迎大家继续阅读 , 谢谢大家!
返回目录 下载代码
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
