ResourceLoader - JiyangM/spring GitHub Wiki

ResourceLoader加载资源。

1.ResourceLoader 作为最上层的接口。DefaultResourceLoader 作为其默认的实现,重新写getResource方法。


	@Override
	public Resource getResource(String location) {
		Assert.notNull(location, "Location must not be null");

		for (ProtocolResolver protocolResolver : this.protocolResolvers) {
			Resource resource = protocolResolver.resolve(location, this);
			if (resource != null) {
				return resource;
			}
		}

		if (location.startsWith("/")) {
			return getResourceByPath(location);
		}
		else 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 (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
			}
			catch (MalformedURLException ex) {
				// No URL -> resolve as resource path.
				return getResourceByPath(location);
			}
		}
	}

	protected Resource getResourceByPath(String path) {
		return new ClassPathContextResource(path, getClassLoader());
	}

	protected static class ClassPathContextResource extends ClassPathResource implements ContextResource {

		public ClassPathContextResource(String path, @Nullable ClassLoader classLoader) {
			super(path, classLoader);
		}

		@Override
		public String getPathWithinContext() {
			return getPath();
		}

		@Override
		public Resource createRelative(String relativePath) {
			String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath);
			return new ClassPathContextResource(pathToUse, getClassLoader());
		}
	}

  • 以"/"开头调用getResourceByPath(location)方法,但是该方法使用的是ClassPath类路径加载资源的方式。
  • 以"classpath:"开头同上。
  • 以上都不成立的话构造空的URL。

2.疑问:DefaultResourceLoader默认采用的时类路径加载资源的方式,那么文件系统的资源如何加载呢?

实际上,文件系统的资源实现是在FileSystemClassLoader中,重写了getResourceByPath方法。

	@Override
	protected Resource getResourceByPath(String path) {
		if (path.startsWith("/")) {
			path = path.substring(1);
		}
		return new FileSystemContextResource(path);
	}

3.ResourceLoader中获取Resource的方法只有一种,只能一次获取一个资源,如何批量获取资源?

ResourcePatternResolver继承ResourceLoader新增加了一个批量获取资源的方法:

	Resource[] getResources(String locationPattern) throws IOException;

4.PathMatchingResourcePatternResolver实现了ResourcePatternResolver接口,支持以Ant风格来批量获取Resource