Spring Resource接口获取资源
1.1.1. Resource简介
在Spring内部实现机制,针对于资源文件(配置的xml文件)有一个统一的接口Resource。
1.1.1.1. 接口定义的方法
1.exists():判断资源文件是否存在。
2.isReadable():用于判断对应资源的内容是否可读。返回false肯定不可读,true也不一定可读。
3.isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。
4.getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。
5.getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。
6.getInputStream():获取当前资源代表的输入流。除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。
1.1.1.2. 接口继承关系
1.1.1.3. 接口实现类
主要常用的有如下:
ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、ServletContextResource和InputStreamResource。
1.1.1.4. ClassPathResource
主要应用于类路径下的资源文件使用classLoader类加载器进行读取使用
使用
ClassPathResource resource = new ClassPathResource("springok/bean/beanFactory.xml");
System.out.println(resource.getFilename());
源码如下:
public ClassPathResource(String path, ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
String pathToUse = StringUtils.cleanPath(path);
if (pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
this.path = pathToUse;
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
}
public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
}
else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
}
else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
return is;
}
1.1.1.5. FileSystemResource
可用来获取文件系统里面的资源。
源码如下:
private final File file;
private final String path;
/**
* Create a new {@code FileSystemResource} from a {@link File} handle.
* <p>Note: When building relative resources via {@link #createRelative},
* the relative path will apply <i>at the same directory level</i>:
* e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"!
* If you prefer to have relative paths built underneath the given root
* directory, use the {@link #FileSystemResource(String) constructor with a file path}
* to append a trailing slash to the root path: "C:/dir1/", which
* indicates this directory as root for all relative paths.
* @param file a File handle
*/
public FileSystemResource(File file) {
Assert.notNull(file, "File must not be null");
this.file = file;
this.path = StringUtils.cleanPath(file.getPath());
}
1.1.1.6. UrlResource
代表URL对应的资源。
源码如下:
public InputStream getInputStream() throws IOException {
URLConnection con = this.url.openConnection();
ResourceUtils.useCachesIfNecessary(con);
try {
return con.getInputStream();
}
catch (IOException ex) {
// Close the HTTP connection (if applicable).
if (con instanceof HttpURLConnection) {
((HttpURLConnection) con).disconnect();
}
throw ex;
}
}
1.1.1.7. ByteArrayResource
针对于字节数组封装的资源,它的构建需要一个字节数组
源码如下:
private final byte[] byteArray;
private final String description;
/**
* Create a new ByteArrayResource.
* @param byteArray the byte array to wrap
*/
public ByteArrayResource(byte[] byteArray) {
this(byteArray, "resource loaded from byte array");
}
1.1.1.8. ServletContextResource
针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。具体还是调用ServletContext 方法。
源码如下:
private final ServletContext servletContext;
private final String path;
public ServletContextResource(ServletContext servletContext, String path) {
// check ServletContext
Assert.notNull(servletContext, "Cannot resolve ServletContextResource without ServletContext");
this.servletContext = servletContext;
Assert.notNull(path, "Path is required");
String pathToUse = StringUtils.cleanPath(path);
if (!pathToUse.startsWith("/")) {
pathToUse = "/" + pathToUse;
}
this.path = pathToUse;
}
1.1.1.9. InputStreamResource
输入流封装的资源,它的构建需要一个输入流。
源码如下:
private final InputStream inputStream;
private final String description;
private boolean read = false;
public InputStreamResource(InputStream inputStream) {
this(inputStream, "resource loaded through InputStream");
}
1.1.2. 通过ResourceLoader获取资源
在Spring里面还定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。它的实现类有很多,这里我们先挑一个DefaultResourceLoader来讲。DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。
源码如下:
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
//classpath:
if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
// Try to parse the location as a URL...
URL url = new URL(location);
return new UrlResource(url);
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
测试:
@Test
public void testResourceLoader() {
ResourceLoader loader = new DefaultResourceLoader();
Resource resource = loader.getResource("http://www.springok.com.");
System.out.println(resource instanceof UrlResource); //true
//注意这里前缀不能使用“classpath*:”,这样不能真正访问到对应的资源,exists()返回false
resource = loader.getResource("classpath:test.txt");
System.out.println(resource instanceof ClassPathResource); //true
resource = loader.getResource("test.txt");
System.out.println(resource instanceof ClassPathResource); //true
}
ApplicationContext接口也继承了ResourceLoader接口,所以它的所有实现类都实现了ResourceLoader接口,都可以用来获取Resource。
对于ClassPathXmlApplicationContext而言,它在获取Resource时继承的是它的父类DefaultResourceLoader的策略。
FileSystemXmlApplicationContext也继承了DefaultResourceLoader,但是它重写了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在获取资源文件时首先也是判断指定的location是否包含“classpath:”前缀,如果包含,则把location中“classpath:”前缀后的资源从类路径下获取出来,当做一个ClassPathResource;否则,继续尝试把location封装成一个URL,返回对应的UrlResource;如果还是失败,则把location指定位置的资源当做一个FileSystemResource进行返回。
1.1.3. 在bean中获取Resource的方式
通过上面内容的介绍,我们知道,在bean中获取Resource主要有以下几种方式:
1.直接通过new各种类型的Resource来获取对应的Resource。
2.在bean里面获取到对应的ApplicationContext,再通过ApplicationContext的getResource(String path)方法获取对应的Resource。
3.直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。
4.通过依赖注入的方式把Resource注入到bean中。示例如下:
使用比较简单如下:
public class ClassA {
//持有一个Resource属性
private Resource resource;
}
配置文件如下:
<bean id="" class="">
<property name="resource">
<value>classpath:applicationContext.xml</value>
</property>
</bean>
Spring Resource接口获取资源相关推荐
- Java-利用Spring提供的Resource/ResourceLoader接口操作资源文件
背景 资源访问接口 主要方法 主要实现类 例子 WritableResource ClassPathResource ServletContextResource 对资源文件编码 资源加载 资源地址表 ...
- Spring.Resource与Spring资源获取方式
讲到资源,就得提下Spring获取资源方式,常用的有两种 通过Resource接口的子类获取资源通过ResourceLoader接口的子类获取资源 Spring.Resource 资源操作函数一览 / ...
- Spring源码分析——资源访问利器Resource之接口和抽象类分析
从今天开始,一步步走上源码分析的路.刚开始肯定要从简单着手.我们先从Java发展史上最强大的框架--Spring...旗下的资源抽象接口Resource开始吧. 我看了好多分析Spring源码的,每每 ...
- Resource接口,及资源
Resource介绍 编码的时候,除了代码本身,我们还需要对外部的资源进行处理.例如:URL资源.URI资源.File资源.ClassPath相关资源.服务器相关资源(VFS等)等等. 而这些资源的处 ...
- Spring系列13:Resource接口及内置实现
本文内容 Resource接口的定义 Resource接口的内置实现 ResourceLoader接口 ResourceLoaderAware 接口 一.Resource接口的定义 Java 的标准 ...
- 【Spring】Resource接口:ClassPathResource
前言 java 1.8 springboot 2.5.4 ClassPathResource读取文件 ClassPathResource 表示从类路径获取资源,它使用线程上下文类加载器.给定的类加载器 ...
- java 接口 提供 路径,Java之Resource接口
接口简介 JDK中提供了java.net.URL这个类来用于获取不同种类的资源(根据不同前缀的url可以获取不同种类的资源).但是URL这个类没有获取classpath和ServletContext下 ...
- Resource接口
[转]https://blog.csdn.net/hbtj_1216/article/details/85487787 参考:官方文档 1 简介 Java标准库中的java.net.URL类和标准处理 ...
- Spring Resource和ResourceLoader源码解析
Spring用Resource接口抽象所有的底层资源,包括File.ClassPath.URL等.ResourceLoader接口是Resource的加载器,根据资源的路径/路径模式获取Resourc ...
最新文章
- php 类中的各种拦截器
- L2-009. 抢红包 结构体排序
- 浏览器到响应页面的全过程
- 手把手教你实现基于LSTM的情感分析(LSTM-based Sentiment) Classification
- Nginx服务的信号控制
- 鸿蒙开发还可以用安卓,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪
- python树的实现
- 【eclipse】启动不了报错java was started but returned exit code=13
- php引用()详解及注意事项
- js打开新窗口Window.open()方法
- HTML页面跳转及传递参数
- 人脸检测实战终极:使用 OpenCV 和 Python 进行人脸对齐
- 领域对象映射到微服务代码模型
- 零基础学python知乎-知乎:参与量化投资实训营是一种怎样的体验?
- python 限定数据范围_python取值范围
- Linux系统编程:IPC信号量
- 前端适配不同型号手机分辨率,100%还原UI设计稿的方案实践
- order by 按照指定顺序排序或自定义顺序排序
- 简单的汇率转换工具---初试AJAX
- SetDlgItemText