Spring源码含有通配符路径解析一.docx

上传人:b****6 文档编号:7297299 上传时间:2023-01-22 格式:DOCX 页数:15 大小:22.79KB
下载 相关 举报
Spring源码含有通配符路径解析一.docx_第1页
第1页 / 共15页
Spring源码含有通配符路径解析一.docx_第2页
第2页 / 共15页
Spring源码含有通配符路径解析一.docx_第3页
第3页 / 共15页
Spring源码含有通配符路径解析一.docx_第4页
第4页 / 共15页
Spring源码含有通配符路径解析一.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

Spring源码含有通配符路径解析一.docx

《Spring源码含有通配符路径解析一.docx》由会员分享,可在线阅读,更多相关《Spring源码含有通配符路径解析一.docx(15页珍藏版)》请在冰豆网上搜索。

Spring源码含有通配符路径解析一.docx

Spring源码含有通配符路径解析一

如果路径包含通配符(?

*,**)spring是怎么处理的?

如果是以classpath*开头的又是如何呢?

先测试分析包含通配符(?

)的。

1./** 

2. * 测试包含通配符:

*,?

的路径 

3. * 

D:

\\workspace-home\\spring-custom\\src\\main\\resources\\spring\\ap?

-context.xml

 

4. * 通过读取配置文件失败的情况,因为此时Spring不支持\\路径的通配符解析 

5. *  

6. * @author lihzh 

7. * @date 2012-5-5 上午10:

53:

53 

8. */ 

9.@Test 

10.public void testAntStylePathFail() { 

11.    String pathOne = "D:

\\workspace-home\\spring-custom\\src\\main\\resources\\spring\\ap?

-context.xml"; 

12.    ApplicationContext appContext = new FileSystemXmlApplicationContext(pathOne); 

13.    assertNotNull(appContext); 

14.    VeryCommonBean bean = null; 

15.    try { 

16.        bean = appContext.getBean(VeryCommonBean.class); 

17.        fail("Should not find the [VeryCommonBean]."); 

18.    } catch (NoSuchBeanDefinitionException e) { 

19.    } 

20.    assertNull(bean); 

21.} 

正如测试用例所写,实际是找不到该Bean的。

这又是为什么?

Spring不是支持通配符吗?

FileSystemXmlApplicationContext的注释里也提到了通配符的情况:

1.* 

The config location defaults can be overridden via {@link #getConfigLocations}, 

2.* Config locations can either denote concrete files like "/myfiles/context.xml" 

3.* or Ant-style patterns like "/myfiles/*-context.xml" (see the 

4.* {@link org.springframework.util.AntPathMatcher} javadoc for pattern details). 

 从代码中寻找答案。

回到上回的else分支中,因为包含通配符,所以进入第一个子分支。

1./** 

2.     * Find all resources that match the given location pattern via the 

3.     * Ant-style PathMatcher. Supports resources in jar files and zip files 

4.     * and in the file system. 

5.     * @param locationPattern the location pattern to match 

6.     * @return the result as Resource array 

7.     * @throws IOException in case of I/O errors 

8.     * @see #doFindPathMatchingJarResources 

9.     * @see #doFindPathMatchingFileResources 

10.     * @see org.springframework.util.PathMatcher 

11.     */ 

12.    protected Resource[] findPathMatchingResources(String locationPattern) throws IOException { 

13.        String rootDirPath = determineRootDir(locationPattern); 

14.        String subPattern = locationPattern.substring(rootDirPath.length()); 

15.        Resource[] rootDirResources = getResources(rootDirPath); 

16.        Set result = new LinkedHashSet(16); 

17.        for (Resource rootDirResource :

 rootDirResources) { 

18.            rootDirResource = resolveRootDirResource(rootDirResource); 

19.            if (isJarResource(rootDirResource)) { 

20.                result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern)); 

21.            } 

22.            else if (rootDirResource.getURL().getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { 

23.                result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirResource, subPattern, getPathMatcher())); 

24.            } 

25.            else { 

26.                result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern)); 

27.            } 

28.        } 

29.        if (logger.isDebugEnabled()) { 

30.            logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result); 

31.        } 

32.        return result.toArray(new Resource[result.size()]); 

33.    } 

 此方法传入的完整的没有处理的路径,从第一行开始,就开始分步处理解析传入的路径,首先是决定“根”路径:

determineRootDir(locationPattern) 

1./** 

2.     * Determine the root directory for the given location. 

3.     * 

Used for determining the starting point for file matching, 

4.     * resolving the root directory location to a java.io.File 

5.     * and passing it into retrieveMatchingFiles, with the 

6.     * remainder of the location as pattern. 

7.     * 

Will return "/WEB-INF/" for the pattern "/WEB-INF/*.xml", 

8.     * for example. 

9.     * @param location the location to check 

10.     * @return the part of the location that denotes the root directory 

11.     * @see #retrieveMatchingFiles 

12.     */ 

13.    protected String determineRootDir(String location) { 

14.        int prefixEnd = location.indexOf(":

") + 1; 

15.        int rootDirEnd = location.length(); 

16.        while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) { 

17.            rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1; 

18.        } 

19.        if (rootDirEnd == 0) { 

20.            rootDirEnd = prefixEnd; 

21.        } 

22.        return location.substring(0, rootDirEnd); 

23.    } 

这个“根”,就是不包含通配符的最长的部分,以我们的路径为例,这个“根”本来应该是:

D:

\\workspace-home\\spring-custom\\src\\main\\resources\\spring\\ ,但是实际上,从determineRootDir的实现可以看出:

 

首先,先找到冒号:

索引位,赋值给prefixEnd 。

 

然后,在从冒号开始到最后的字符串中,循环判断是否包含通配符,如果包含,则截断最后一个由"/"分割的部分,例如:

在我们路径中,就是最后的ap?

-context.xml这一段。

再循环判断剩下的部分,直到剩下的路径中都不包含通配符。

如果查找完成后,rootDirEnd=0了,则将之前赋值的prefixEnd的值赋给rootDirEnd,也就是":

"所在的索引位。

 

最后,将字符串从开始截断rootDirEnd。

 

我们的问题,就出在关键的第二步,Spring这里只在字符串中查找"/",并没有支持"\\"这样的路径分割方式,所以,自然找不到"\\",rootDirEnd=-1+1=0。

所以循环后,阶段出来的路径就是D:

 ,自然Spring会找不到配置文件,容器无法初始化。

 

基于以上分析,我们将路径修改为:

D:

/workspace-home/spring-custom/src/main/resources/spring/ap?

-context.xml,

测试通过。

 

刚才仅仅分析了,我们之前路径的问题所在,还有一点我想也是大家关心的,就是通配符是怎么匹配的呢?

那我们就继续分析源码,回到findPathMatchingResources 方法。

 

将路径分成包含通配符和不包含的两部分后,Spring会将根路径生成一个Resource,用的还是getResources方法。

然后检查根路径的类型,是否是Jar路径?

是否是VFS路径?

对于我们这种普通路径,自然走到最后的分支。

1./** 

2.     * Find all resources in the file system that match the given location pattern 

3.     * via the Ant-style PathMatcher. 

4.     * @param rootDirResource the root directory as Resource 

5.     * @param subPattern the sub pattern to match (below the root directory) 

6.     * @return the Set of matching Resource instances 

7.     * @throws IOException in case of I/O errors 

8.     * @see #retrieveMatchingFiles 

9.     * @see org.springframework.util.PathMatcher 

10.     */ 

11.    protected Set doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) 

12.            throws IOException { 

13. 

14.        File rootDir; 

15.        try { 

16.            rootDir = rootDirResource.getFile().getAbsoluteFile(); 

17.        } 

18.        catch (IOException ex) { 

19.            if (logger.isWarnEnabled()) { 

20.                logger.warn("Cannot search for matching files underneath " + rootDirResource + 

21.                        " because it does not correspond to a directory in the file system", ex); 

22.            } 

23.            return Collections.emptySet(); 

24.        } 

25.        return doFindMatchingFileSystemResources(rootDir, subPattern); 

26.    } 

1./** 

2.     * Retrieve files that match the given path pattern, 

3.     * checking the given directory and its subdirectories. 

4.     * @param rootDir the directory to start from 

5.     * @param pattern the pattern to match against, 

6.     * relative to the root directory 

7.     * @return the Set of matching File instances 

8.     * @throws IOException if directory contents could not be retrieved 

9.     */ 

10.    protected Set retrieveMatchingFiles(File rootDir, String pattern) throws IOException { 

11.        if (!

rootDir.exists()) { 

12.            // Silently skip non-existing directories. 

13.            if (logger.isDebugEnabled()) { 

14.                logger.debug("Skipping [" + rootDir.getAbsolutePath() + "] because it does not exist"); 

15.            } 

16.            return Collections.emptySet(); 

17.        } 

18.        if (!

rootDir.isDirectory()) { 

19.            // Complain louder if it exists but is no directory. 

20.            if (logger.isWarnEnabled()) { 

21.                logger.warn("Skipping [" + rootDir.getAbsolutePath() + "] because it does not denote a directory"); 

22.            } 

23.            return Collections.emptySet(); 

24.        } 

25.        if (!

rootDir.canRead()) { 

26.            if (logger.isWarnEnabled()) { 

27.                logger.warn("Cannot search for matching files underneath directory [" + rootDir.getAbsolutePath() + 

28.                        "] because the application is not allowed to read the directory"); 

29.            } 

30.            return Collections.emptySet(); 

31.        } 

32.        String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/"); 

33.        if (!

pattern.startsWith("/")) { 

34.            fullPattern += "/"; 

35.        } 

36.        fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/"); 

37.        Set result = new LinkedHashSet(8); 

38.        doRetrieveMatchingFiles(fullPattern, rootDir, result); 

39.        return result; 

40.    } 

1./** 

2.     * Recursively retrieve files that match the given pattern, 

3.     * adding them to the given result list. 

4.     * @param fullPattern the pattern to match against, 

5.     * with prepended root directory path 

6.     * @param dir the current directory 

7.     * @param result the Set of matching File instances to add to 

8.     * @throws IOException if directory contents could not be retrieved 

9.     */ 

10.    protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set result) throws IOException { 

11.        if (logger.isDebugEnabled()) { 

12.            logger.debug("Searching directory [" + dir.getAbsolutePath() + 

13.                    "] for files matching pattern [" + fullPattern + "]"); 

14.        } 

15.        File[] dirContents = dir.listFiles(); 

16.        if (dirContents == null) { 

17.            if (logger.isWarnEnabled()) { 

18.                logger.warn("Could not retrieve contents of directory [" + dir.getAbsolutePath() + "]"); 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 研究生入学考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1