欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

弄清资源、资源加载器和容器之间的微妙关系 - 在 Java 中,资源会被抽象成 url,通过 url 前面的协议(如 file:、classpath:)来处理不同的操作逻辑,资源是一个接口

最编程 2024-03-09 20:04:40
...

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,高级容器支持统一资源加载