Java提供的Java.net.URL类可做资源访问,也提供IO流进行读写本地文件;
传统的资源访问操作复杂,对于某些特定的资源,传统的资源访问没有提供专门的API访问,如CLASSPATH下的某个文件,或者访问ServletContext下的某个文件,不能够通过传统的方式进行访问。
a.传统的资源访问
访问传统的网络资源通过java.net.url类提供的方法进行访问;
URL以统一的方法访问各种资源,获得URL后,通过openStream()方法打开输入流,需要手动配置IO流,实例代码如下
b.Spring的资源访问
(1)Resource接口
Spring的资源访问通过Resource接口实现,Resource接口是低级资源访问方式的抽象,也是所有资源访问类的父接口;
即使不使用Spring框架,也可以使用Resource作为工具类,代替URL
Resource接口内有如下6个重要方法
getInputStream():定位并打开资源,返回资源对应的输入流,每次调用都返回新的输入流,调用者需要负责关闭输入流;
exists()显示该资源是否存在
isOpen()返回资源文件是否打开,如果资源文件不能多次读取,每次读取结束应该显示关闭,防止资源泄漏。
getDescription()
getFile
getURL
(2)Resource实现类
Spring提供Resource接口的大量实现类
UrlResource
ClassPathResource
FileSystemResource
ServletContextResource
InputStreamResource
ByteArrayResource
a.UrlResource
访问网络资源通过UrlResource类实现,用于访问之前通过URL类访问的资源对象,UrlResource类实现Resource接口,完全支持Resource的全部API,Resource接口的方法,UrlResource类提供实现
b.ClassPathResource
用来加载在CLASSPATH路径中搜索到的资源,方便CLASSPATH里的资源,特别对于web应用,ClassPathResource可自动搜索WEB-INF/classes下的资源文件,无需使用绝对路径进行访问。
c.FileSystemResource
FileSystemResource对java.io.File包装,用于访问本地文件
d.ServletContextResource
e.InputStreamResource
f.ByteArrayResource
字节数组是一种常见的信息传输方式,通过网络Socket的信息交换,或者线程之间的信息交换,字节数组都被做信息载体,ByteArrayResource可以将字节数组包装成Resource使用
(3)ResourceLoader接口和ResourceLoaderAware接口
ResourceLoader:实现类可以返回一个Resource实例
ResourceLoaderAware:实现类必须获得ResourceLoader引用
Resource接口仅包含一个方法,用于返回一个Resource实例,该实例可以重复使用;
ApplicationContext的实现类都实现ResourceLoader接口,因此ApplicationContext可用来获得Resource实例。
某个ApplicationContext实例获取Resource实例时,默认采取与ApplicationContext相同的资源访问策略。
好的习惯是:以接口的形式向用户展示,不对用户展示具体的实现类
ResourceLoader:用于生成可以重复使用的Resource(接口)
ResourceLoaderAware 接口(实现类可以获取ResourceLoader)
该接口只有一个方法,setResourceLoader,该方法用于设置实例需要使用的ResourceLoader,如果将该实例部署在ApplicationContext中,容器会将本身当成ResourceLoader注入,部署在容器中的ResourceLoaderAware实例能够获得容器的引用,ApplicationContext类已经实现ResourceLoader接口,因此,ApplicationContext可以用来load资源
使用Resource作为属性
如果bean需要访问资源,有如下解决方案:
a.代码中创建Resource实例
b.使用依赖注入
对于第一种方式,需要在程序中提供资源的路径,当资源的位置发生变化时,需要修改对应的程序,建议采用第二中方式
将Resource作为bean的参数,生成bean的实例后对bean的Resource属性进行依赖注入,通过在配置文件中使用特定的访问前缀,可强制使用特定的Resource实现
通过将Resource作为bean的属性,进行依赖注入,可以动态配置资源的路径和访问策略
(4)ApplicationContext中使用资源
实例化ApplicationContext通常采用其实现类, ApplicationContext的实现类通常有以下几个:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
XmlWebApplicationContext
对应一下三种资源访问方式(因为ApplicaitonContext实现ResourceLoader接口,因此可以生成Resource实例)
ClassPathResource
FileSystemResource
ServletContextResource
也可以使用前缀确定资源访问策略,但是使用前缀确定,仅仅对当此有效(即对读取bean的配置文件有效),以后还是要根据ApplicationContext的实现方式采用对应的资源访问策略,获取资源时也可以采用前缀确定资源访问方式