Resource:
在Java中,资源会被抽象成url,通过url前面的协议(如file:,classpath:)来处理不同的操作逻辑,resource是一个接口
Resource家族
具体的资源访问由其实现类完成,EncodedResource提供资源的编码处理,AbstractResource提供Resource的大量的默认公共实现,下面为特定类型的实现,ServletContextResource为访问web容器上下文资源设计的类,classPathResource方便访问类加载路径下的资源,尤其对于web应用来说,可以直接访问WEB-INF/classes下的资源,无需通过绝对路径,FileSysteResource用于访问系统资源,和File差不多,Resource只提供读操作,FileSysteResource继承WritableResource使其拥有写的能力。
Spring实现
上述通过ResourceLoader实现
DefaultResourceLoader获取Resource的具体实现类的实例
//获取Resource的具体实现类实例
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
//ProtocolResolver ,用户自定义协议资源解决策略
for (ProtocolResolver protocolResolver : getProtocolResolvers()) {
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
}
}
//如果是以/开头,则构造ClassPathContextResource返回
if (location.startsWith("/")) {
return getResourceByPath(location);
}
//若以classpath:开头,则构造 ClassPathResource 类型资源并返回,在构造该资源时,
// 通过 getClassLoader()获取当前的 ClassLoader
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
//构造 URL ,尝试通过它进行资源定位,若没有抛出 MalformedURLException 异常,
// 则判断是否为 FileURL , 如果是则构造 FileUrlResource 类型资源,否则构造 UrlResource。
// 若在加载过程中抛出 MalformedURLException 异常,
// 则委派 getResourceByPath() 实现资源定位加载
try {
// Try to parse the location as a URL...
URL url = new URL(location);
return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
ResourcePattenrnResolver 实现了ant风格的资源访问
ApplicationContext接口继承了ResourcePattenrnResolver,AbstractApplicationContext继承了ResourcePattenrnResolver,高级容器支持统一资源加载