Resource,ResourceLoader,容器之间的微妙关
Resource,ResourceLoader,容器之间的微妙关系
Resource
Spring将需要读取的资源抽象为Resource进行处理,
public interface Resource extends InputStreamSource {
EncodedResource提供对Resource资源的编解码等处理。
public class EncodedResource implements InputStreamSource {
AbstractResource实现了Resource的大部分功能,
public abstract class AbstractResource implements Resource {
基于AbstractResource Spring提供了三种可以直接使用的实例:
ServletContextResource,ClassPathResource,FileSystemResource
Resource接口中定义的都是读类型的方法,而如果具体类型的Resource实例需要拥有写类型的方法需要实现WritableResource接口
public interface WritableResource extends Resource {
ResourceLoader
Spring中每种类型的资源都有对应的Resource实现类对应,是否可以不使用对应的Resource,在知道资源位置的情况下就直接使用资源呢?
ResourceLoader强大的资源加载方式
-
自动识别classpath,file,等资源地址前缀
-
支持自动解析Ant风格带通配符的资源地址
Ant
路径匹配表达式,用来对URI进行匹配
和通配符的作用差不多,只是适用面仅仅用于路径匹配。
?表示匹配任意类型单字符
test/p?ocess可以匹配 test/process,test/poocess 但是不能匹配 test/pocess
*表示匹配0个或任意数量的字符
/test/*.jsp 匹配 test路径下的.jsp文件
/test/*/path 匹配 /test/path,/test/a/path,/test/b/path但是不匹配/test/a/b/path
**表示匹配0个或者更多的目录
/test/**/path 匹配 /test/path,/test/a/path,/test/b/path,/test/a/b/path
的
ResourcePatternResolver,PathMatchingResourcePatternResolver
这个接口是Spring提供的解析 Ant 表达式的接口,定义了解析Ant表达式的方法,PathMatchingResourcePatternResolver实现了这个接口
public class AntPathMatcher implements PathMatcher {
ResourceLoader:Spring提供了强大的资源加载方式,根据传入的资源地址,自动去构建出适配该资源的Resource实现类实例
实现不同Resource的加载策略,按需返回特定类型的Resource
DefaultResourceLoader:提供Resource接口的实现
根据不同路径返回不同的具体Resource实现类实例---策略模式
容器与ResourceLoader的关系:
ApplicationContext继承ResourcePatternResolver
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
ResourcePatternResolver继承ResourceLoader
public interface ResourcePatternResolver extends ResourceLoader {
AbstractApplicationContext继承自DefaultResourceLoader
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
AbstractApplicationContext的如下方法获取ResourcePatternResolver
生成后在AbstractApplicationContext构造函数中使用
构造PathMatchingResourcePatternResolver的时候,将自己AbstractApplicationContext传入其中,充当ResourceLoader
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
然后在类AbstractApplicationContext中getResources方法被调用获取资源时,调用资源解析器解析资源
@Override
public Resource[] getResources(String locationPattern) throws IOException {
return this.resourcePatternResolver.getResources(locationPattern);
}
综上可以知道ApplicationContext的任何实现类的实例本身就可以作为一个ResourceLoader,所以高级容器支持多资源的加载