Spring中资源的加载原来是这么一回事啊! (5)

PathMatchingResourcePatternResolver 中的 getResource 方法的实现是调用了 传入的 ResourceLoader 或者默认的 DefaultResourceLoader , 具体的代码实现如下:

/** * 调用getResourceLoader 获取当前的 ResourceLoader * @param location the resource location * @return */ @Override public Resource getResource(String location) { return getResourceLoader().getResource(location); } /** * Return the ResourceLoader that this pattern resolver works with. */ public ResourceLoader getResourceLoader() { return this.resourceLoader; } 3.5.3 getResources

实现了 ResourcePatternResolver 的 getResources 方法,可以通过 location 加载多个资源,进行分类处理,如果是没有 classpath*: 前缀以及不包含通配符的情况下直接调用当前类的 ResourceLoader 来进行处理,其他按具体来处理,主要涉及两个方法 #findPathMatchingResources(...) 与 #findAllClassPathResources(...)

@Override public Resource[] getResources(String locationPattern) throws IOException { Assert.notNull(locationPattern, "Location pattern must not be null"); //1. 判断 是不是classpath* 开头的 if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) { //1.1.进行路径匹配校验 是否包含通配符 // a class path resource (multiple resources for same name possible) if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) { // a class path resource pattern return findPathMatchingResources(locationPattern); } else { //1.2 不包含通配符 // all class path resources with the given name return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length())); } } else { // 2. 不是classpath前缀开头 // Generally only look for a pattern after a prefix here, // and on Tomcat only after the "*/" separator for its "war:" protocol. int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 : locationPattern.indexOf(':') + 1); //2.1 校验是否包含通配符 if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) { // a file pattern return findPathMatchingResources(locationPattern); } else { //2.2 不包含通配符 使用内部 ResourceLoader 进行资源加载 默认是 DefaultReourceLoader // a single resource with the given name return new Resource[] {getResourceLoader().getResource(locationPattern)}; } } } 3.5.4 findPathMatchingResources

上面代码中我们可以看到,当存在通配符时都会执行 #findPathMatchingResources(...) 方法,我们来看一下方法的定义:

/** * 通过ant解析器来对给定的路径下的所有模糊资源进行解析和匹配 * 支持jar和zip以及系统中的文件资源 * Find all resources that match the given location pattern via the * Ant-style PathMatcher. Supports resources in jar files and zip files * and in the file system. * @param locationPattern the location pattern to match * @return the result as Resource array * @throws IOException in case of I/O errors * @see #doFindPathMatchingJarResources * @see #doFindPathMatchingFileResources * @see org.springframework.util.PathMatcher */ protected Resource[] findPathMatchingResources(String locationPattern) throws IOException { //解析根路径 String rootDirPath = determineRootDir(locationPattern); //解析到子路径 String subPattern = locationPattern.substring(rootDirPath.length()); //获取根路径的资源 Resource[] rootDirResources = getResources(rootDirPath); Set<Resource> result = new LinkedHashSet<>(16); //遍历 for (Resource rootDirResource : rootDirResources) { rootDirResource = resolveRootDirResource(rootDirResource); URL rootDirUrl = rootDirResource.getURL(); //判断资源是不是 bundle 类型 if (equinoxResolveMethod != null && rootDirUrl.getProtocol().startsWith("bundle")) { URL resolvedUrl = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirUrl); if (resolvedUrl != null) { rootDirUrl = resolvedUrl; } rootDirResource = new UrlResource(rootDirUrl); } //判断资源是否是 vfs 类型的 if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher())); } //判断是否是 jar 形式的 else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) { result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern)); } //如果都不是 else { result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern)); } } if (logger.isTraceEnabled()) { logger.trace("Resolved location pattern [" + locationPattern + "] to resources " + result); } //转换为数组返回 return result.toArray(new Resource[0]); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdsgx.html