zoukankan      html  css  js  c++  java
  • 加载 bean*.xml

    入口

    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean*.xml");

        /**
             * Main entry point.
             * @return {@code true} if the string matches against the pattern, or {@code false} otherwise.
             */
            public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
                Matcher matcher = this.pattern.matcher(str);
                if (matcher.matches()) {
                    if (uriTemplateVariables != null) {
                        // SPR-8455
                        Assert.isTrue(this.variableNames.size() == matcher.groupCount(),
                                "The number of capturing groups in the pattern segment " + this.pattern +
                                " does not match the number of URI template variables it defines, which can occur if " +
                                " capturing groups are used in a URI template regex. Use non-capturing groups instead.");
                        for (int i = 1; i <= matcher.groupCount(); i++) {
                            String name = this.variableNames.get(i - 1);
                            String value = matcher.group(i);
                            uriTemplateVariables.put(name, value);
                        }
                    }
                    return true;
                }
                else {
                    return false;
                }
            }
        }

    最后发现 java.util.regex.Pattern 调用matches() 方法

    从而得知 支持正则表达式。

    总结:

    classpath:bean*.xml
    冒号前半部分是为了获取 classpath 文件路径,然后file.lists() 递归循环获取所有 文件路径 ,逐一与冒号后面的 pattern 匹配。


    冒号分析

    /**
     * A {@link ResourcePatternResolver} implementation that is able to resolve a
     * specified resource location path into one or more matching Resources.
     * The source path may be a simple path which has a one-to-one mapping to a
     * target {@link org.springframework.core.io.Resource}, or alternatively
     * may contain the special "{@code classpath*:}" prefix and/or
     * internal Ant-style regular expressions (matched using Spring's
     * {@link org.springframework.util.AntPathMatcher} utility).
     * Both of the latter are effectively wildcards.
     *
     * <p><b>No Wildcards:</b>
     *
     * <p>In the simple case, if the specified location path does not start with the
     * {@code "classpath*:}" prefix, and does not contain a PathMatcher pattern,
     * this resolver will simply return a single resource via a
     * {@code getResource()} call on the underlying {@code ResourceLoader}.
     * Examples are real URLs such as "{@code file:C:/context.xml}", pseudo-URLs
     * such as "{@code classpath:/context.xml}", and simple unprefixed paths
     * such as "{@code /WEB-INF/context.xml}". The latter will resolve in a
     * fashion specific to the underlying {@code ResourceLoader} (e.g.
     * {@code ServletContextResource} for a {@code WebApplicationContext}).
     *
     * <p><b>Ant-style Patterns:</b>
     *
     * <p>When the path location contains an Ant-style pattern, e.g.:
     * <pre class="code">
     * /WEB-INF/*-context.xml
     * com/mycompany/**&#47;applicationContext.xml
     * file:C:/some/path/*-context.xml
     * classpath:com/mycompany/**&#47;applicationContext.xml</pre>
     * the resolver follows a more complex but defined procedure to try to resolve
     * the wildcard. It produces a {@code Resource} for the path up to the last
     * non-wildcard segment and obtains a {@code URL} from it. If this URL is
     * not a "{@code jar:}" URL or container-specific variant (e.g.
     * "{@code zip:}" in WebLogic, "{@code wsjar}" in WebSphere", etc.),
     * then a {@code java.io.File} is obtained from it, and used to resolve the
     * wildcard by walking the filesystem. In the case of a jar URL, the resolver
     * either gets a {@code java.net.JarURLConnection} from it, or manually parses
     * the jar URL, and then traverses the contents of the jar file, to resolve the
     * wildcards.
     *
     * <p><b>Implications on portability:</b>
     *
     * <p>If the specified path is already a file URL (either explicitly, or
     * implicitly because the base {@code ResourceLoader} is a filesystem one,
     * then wildcarding is guaranteed to work in a completely portable fashion.
     *
     * <p>If the specified path is a classpath location, then the resolver must
     * obtain the last non-wildcard path segment URL via a
     * {@code Classloader.getResource()} call. Since this is just a
     * node of the path (not the file at the end) it is actually undefined
     * (in the ClassLoader Javadocs) exactly what sort of a URL is returned in
     * this case. In practice, it is usually a {@code java.io.File} representing
     * the directory, where the classpath resource resolves to a filesystem
     * location, or a jar URL of some sort, where the classpath resource resolves
     * to a jar location. Still, there is a portability concern on this operation.
     *
     * <p>If a jar URL is obtained for the last non-wildcard segment, the resolver
     * must be able to get a {@code java.net.JarURLConnection} from it, or
     * manually parse the jar URL, to be able to walk the contents of the jar,
     * and resolve the wildcard. This will work in most environments, but will
     * fail in others, and it is strongly recommended that the wildcard
     * resolution of resources coming from jars be thoroughly tested in your
     * specific environment before you rely on it.
     *
     * <p><b>{@code classpath*:} Prefix:</b>
     *
     * <p>There is special support for retrieving multiple class path resources with
     * the same name, via the "{@code classpath*:}" prefix. For example,
     * "{@code classpath*:META-INF/beans.xml}" will find all "beans.xml"
     * files in the class path, be it in "classes" directories or in JAR files.
     * This is particularly useful for autodetecting config files of the same name
     * at the same location within each jar file. Internally, this happens via a
     * {@code ClassLoader.getResources()} call, and is completely portable.
     *
     * <p>The "classpath*:" prefix can also be combined with a PathMatcher pattern in
     * the rest of the location path, for example "classpath*:META-INF/*-beans.xml".
     * In this case, the resolution strategy is fairly simple: a
     * {@code ClassLoader.getResources()} call is used on the last non-wildcard
     * path segment to get all the matching resources in the class loader hierarchy,
     * and then off each resource the same PathMatcher resolution strategy described
     * above is used for the wildcard subpath.
     *
     * <p><b>Other notes:</b>
     *
     * <p><b>WARNING:</b> Note that "{@code classpath*:}" when combined with
     * Ant-style patterns will only work reliably with at least one root directory
     * before the pattern starts, unless the actual target files reside in the file
     * system. This means that a pattern like "{@code classpath*:*.xml}" will
     * <i>not</i> retrieve files from the root of jar files but rather only from the
     * root of expanded directories. This originates from a limitation in the JDK's
     * {@code ClassLoader.getResources()} method which only returns file system
     * locations for a passed-in empty String (indicating potential roots to search).
     *
     * <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not
     * guaranteed to find matching resources if the root package to search is available
     * in multiple class path locations. This is because a resource such as
     * <pre class="code">
     *     com/mycompany/package1/service-context.xml
     * </pre>
     * may be in only one location, but when a path such as
     * <pre class="code">
     *     classpath:com/mycompany/**&#47;service-context.xml
     * </pre>
     * is used to try to resolve it, the resolver will work off the (first) URL
     * returned by {@code getResource("com/mycompany");}. If this base package
     * node exists in multiple classloader locations, the actual end resource may
     * not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same
     * Ant-style pattern in such a case, which will search <i>all</i> class path
     * locations that contain the root package.
     *
     * @author Juergen Hoeller
     * @author Colin Sampaleanu
     * @author Marius Bogoevici
     * @author Costin Leau
     * @since 1.0.2
     * @see #CLASSPATH_ALL_URL_PREFIX
     * @see org.springframework.util.AntPathMatcher
     * @see org.springframework.core.io.ResourceLoader#getResource(String)
     * @see ClassLoader#getResources(String)
     */
    public class PathMatchingResourcePatternResolver implements ResourcePatternResolver
    View Code

    PathMatchingResourcePatternResolver 的部分方法↓

     1   @Override
     2     public Resource[] getResources(String locationPattern) throws IOException {
     3         Assert.notNull(locationPattern, "Location pattern must not be null");
     4         if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
     5             // a class path resource (multiple resources for same name possible)
     6             if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
     7                 // a class path resource pattern
     8                 return findPathMatchingResources(locationPattern);
     9             }
    10             else {
    11                 // all class path resources with the given name
    12                 return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
    13             }
    14         }
    15         else {
    16             // Only look for a pattern after a prefix here
    17             // (to not get fooled by a pattern symbol in a strange prefix).
    18             int prefixEnd = locationPattern.indexOf(":") + 1;
    19             if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
    20                 // a file pattern
    21                 return findPathMatchingResources(locationPattern);
    22             }
    23             else {
    24                 // a single resource with the given name
    25                 return new Resource[] {getResourceLoader().getResource(locationPattern)};
    26             }
    27         }
    28     }

    locationPattern 的两次值分别是:

    1. classpath:bean*.xml
    2. classpath:

    第8行↑ 调用的方法参数是1,在该方法中再一次调用getResources,然后传的参数是2 (目的是为了获取rootDirResources)

    第一个if else 是区分classpath*: 这是固定写法↓ ,然后回处理冒号左右↑

      /**
         * Pseudo URL prefix for all matching resources from the class path: "classpath*:"
         * This differs from ResourceLoader's classpath URL prefix in that it
         * retrieves all matching resources for a given name (e.g. "/beans.xml"),
         * for example in the root of all deployed JAR files.
         * @see org.springframework.core.io.ResourceLoader#CLASSPATH_URL_PREFIX
         */
        String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

    如果是classpath: 这是固定写法↓ ,则处理冒号左右

      /** Pseudo URL prefix for loading from the class path: "classpath:" */
        String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

    如果是冒号右边是路径,则处理这个资源。↑

    如果是冒号右边不是路径,则继续处理。↑【25行】——如下:

     1   @Override
     2     public Resource getResource(String location) {
     3         Assert.notNull(location, "Location must not be null");
     4         if (location.startsWith("/")) {
     5             return getResourceByPath(location);
     6         }
     7         else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
     8             return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
     9         }
    10         else {
    11             try {
    12                 // Try to parse the location as a URL...
    13                 URL url = new URL(location);
    14                 return new UrlResource(url);
    15             }
    16             catch (MalformedURLException ex) {
    17                 // No URL -> resolve as resource path.
    18                 return getResourceByPath(location);
    19             }
    20         }
    21     }

    第7行,必须以classpath: 开始。↑

    第8行,new ClassPathResource 的实例,其中第一个参数path为"" ,第二个参数为getClassLoader() 返回的实例。↑

     1   protected URL resolveURL() {
     2         if (this.clazz != null) {
     3             return this.clazz.getResource(this.path);
     4         }
     5         else if (this.classLoader != null) {
     6             return this.classLoader.getResource(this.path);
     7         }
     8         else {
     9             return ClassLoader.getSystemResource(this.path);
    10         }
    11     }

    第6行 ,返回了类路径。↑   结果如下:↓

    file:/E:/e/workspace/context/target/classes/
  • 相关阅读:
    读书笔记——吴军《态度》
    JZYZOJ1237 教授的测试 dfs
    NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论
    [JZYZOJ 1288][洛谷 1005] NOIP2007 矩阵取数 dp 高精度
    POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数
    POJ2157 Check the difficulty of problems 概率DP
    HDU3853 LOOPS 期望DP 简单
    Codeforces 148D. Bag of mice 概率dp
    POJ3071 Football 概率DP 简单
    HDU4405 Aeroplane chess 飞行棋 期望dp 简单
  • 原文地址:https://www.cnblogs.com/zno2/p/4692818.html
Copyright © 2011-2022 走看看