介绍
本文介绍的spring框架中对各种资源的抽象概念与一些基础实现。
Resource接口
主要是对具体的url、file、class之类的资源的访问包装抽象,他把这些东西都统一抽象为`Resource`。类似于我们的万物皆对象一样。
Resource源码
package org.springframework.core.io;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import org.springframework.lang.Nullable;
/**
* Interface for a resource descriptor that abstracts from the actual
* type of underlying resource, such as a file or class path resource.
*
* 从底层资源的实际类型(例如文件或类路径资源)中抽象出来的资源描述符的接口。
* 如果 InputStream 以物理形式存在,则可以为每个资源打开它,但只能为某些资源返回 URL 或文件句柄。 实际行为是特定于实现的。
*/
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
boolean isFile();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
ReadableByteChannel readableChannel() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
UrlResource
用于封装可通过网络访问的 java.net.URL 标识的对象,例如文件路径(file:)、http路径(http:)、ftp路径(ftp:)等
ClassPathResource
用于封装从类路径中获取的资源(classpath:)
FileSystemResourc
通过java.io.file实现Resource接口。可解析路径为File和URL对象,用于操作文件的。是阻塞的。(可以设置为通过java.nio.file.Path实现,不建议这么做,因为有PathResource)
PathResource
通过java.nio.file.Path实现Resource接口。可解析路径为File和URL对象,用于操作文件的。这个是响应式的。
ServletContextResource
实现了Resource接口的ServletContext
InputStreamResource
实现了Resource接口的ServletContext
ByteArrayResource
实现了Resource接口的字节数组
ResourceLoader接口
核心定义一个通过路径获取Resource的功能。
ResourceLoader源码
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
ResourcePatternResolver接口
ResourcePatternResolver是对ResourceLoader扩展,它多了一个通过匹配规则获取resource数组的API
ResourcePatternResolver
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}
ResourceLoaderAware接口
定义了一个设置ResourceLoader的API。自定义的容器完全可以自己随便通过某种方式设置ResourceLoader。
ResourceLoaderAware
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
自定义资源的声明与使用
说白了,就是在容器内声明一个组件,有个地方依赖使用它
使用案例
@Component
// 表名这是一个组件类,由spring容器创建一个组件实例
public class MyBean {
private final Resource[] templates;
public MyBean(@Value("${templates.path}") Resource[] templates) {
this.templates = templates;
}
// ...
}
应用上下文与资源路径
说了下ApplicationContext的几种实现与注意事项。官网由此去
点击查看代码
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml");
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
此处不翻译官网的了,说下自己的看法。一般应用上下文指的是ApplicationContext接口的某一个具体实现bean。这个bean可以看作为一个IOC容器,这个容器里面有一系列的资源(Resource)。这些资源的来源多种多样,有的是class文件,有的是xml文件,有的是yml文件……所以他们由各自的资源加载器(ReaourceLoader)来加载。