Classpath path issues in the Spring MAVEN project

Source: Internet
Author: User
Tags addall

Please visit the original blog: http://zhuqiuhui.space/Blogs/2017/03/spring-classpath.html

Spring in the Classpath and classpath* has been the development of the heart, no time to calm down to study, finally coherent. Summary of the online also more, a variety of statements, but also as a personal interpretation of spring in the source code, so the next time to use the heart more comfortable, welcome support.

I. Description of the problem

The path lookup order is unknown when the import resource file is used with spring (doubt in development), or the load resource fails (does not know how to change the path).

Second, classpath code analysis

Directly on the code, this is the main class Pathmatchingresourcepatternresolver class in the code, located under the package Org.springframework.core.io.support, the getresources in the class Functions are the core of logic, as follows:

Public resource[] Getresources (String locationpattern) throws IOException {if Locationpattern.startswith (CLASSPATH _all_url_prefix)) {if (Getpathmatcher (). Ispattern (Locationpattern.substring (Classpath_all_url_prefix.length ())) {//Case 1: If it starts with classpath* and contains.  
        or *, for example, find: classpath*: Applicationcontext-*.xml return findpathmatchingresources (Locationpattern); else {//Case 2: not included. or *, direct full name lookup, such as find: classpath*: Applicationcontext-test.xml return findallclasspathresources (locationpattern.subs  
        Tring (Classpath_all_url_prefix.length ()));  
        } else {//to classpath: Opening int prefixend = Locationpattern.indexof (":") +1; if (Getpathmatcher (). Ispattern (Locationpattern.substring (prefixend)) {//Case 3: If not beginning with classpath* and contained.  
        or *, for example, find: Classpath:applicationcontext-*.xml return findpathmatchingresources (Locationpattern);  
       } else {//Case 4: If not beginning with classpath* and not included. or *, such as looking for: Classpath:applicationcontext-test.xml returnnew resource[] {getresourceloader (). GetResource (Loca  
        Tionpattern)};  }  
    }  
}


2.1 If starting with classpath* and containing. or *

For example, find: classpath*: Applicationcontext-*.xml, using the Findpathmatchingresources function, look at the function:

                   
Protected resource[] Findpathmatchingresources (String locationpattern) throws IOException {/* function det
                                                   The Erminerootdir function is to get the directory that can be determined, such as classpath*:/aaa/bbb/applicationcontext-*.xml to return classpath*:/aaa/bbb/
    Classpath*:/aaa/*/applicationcontext-*.xml, then return to classpath*:/aaa/(code will no longer paste, interested can look at the source code) * *
    String Rootdirpath = Determinerootdir (Locationpattern);
    Gets the contents of the Locationpattern string subpattern = Locationpattern.substring (Rootdirpath.length ());
    Recursive loading has been determined by the content resource[] rootdirresources = getresources (Rootdirpath);
    Set result = new linkedhashset<> (16);
        for (Resource rootdirresource:rootdirresources) {Rootdirresource = Resolverootdirresource (Rootdirresource);
        URL Rootdirurl = Rootdirresource.geturl (); if (Equinoxresolvemethod!=null) {if (Rootdirurl.getprotocol (). StartsWith ("bundle")) {ROOTDI Rurl = (URL) reflectionutils.invokeMethod (Equinoxresolvemethod,null, Rootdirurl);
            Rootdirresource = new Urlresource (Rootdirurl); } if (Rootdirurl.getprotocol (). StartsWith (RESOURCEUTILS.URL_PROTOCOL_VFS)) {/are general J Boss VFS resource: "VFS" Result.addall (Vfsresourcematchingdelegate.findmatchingresources (Rootdirurl, Subpatte
        RN, Getpathmatcher ())); } elseif (Resourceutils.isjarurl (rootdirurl) | | isjarresource (ROOTDIRRESOURCE)) {/Is zip, jar, WSJA
        R or Vfszip one loads the Result.addall (dofindpathmatchingjarresources (Rootdirresource, Rootdirurl, Subpattern));
        else {Result.addall (dofindpathmatchingfileresources (Rootdirresource, subpattern)); } if (logger.isdebugenabled ()) {Logger.debug ("Resolved location pattern [" + Locationpattern +] to Res
    Ources "+ result);
Return Result.toarray (New Resource[result.size ()); }

Overall: The function splits the locationpattern into two parts: Rootdirpath and Subpattern,rootdirpath are root paths, Subpattern are subdirectory path matching rule strings. Iterate through all subdirectories under the root directory, and get all subdirectories in the Dofindpathmatchingfileresources (Rootdirresource, Subpattern) method, and then match subpattern one by one, one at a child directory.


2.2 If starting with classpath* and not included. or *, direct full name lookup

For example, find: classpath*: Applicationcontext-test.xml, using the Findallclasspathresources function, look at the function:

Protected resource[] Findallclasspathresources (string location) throws IOException {
    string path = location;
    if (Path.startswith ("/")) {
        path = path.substring (1);
    }
    Set result = dofindallclasspathresources (path);
    if (logger.isdebugenabled ()) {
        Logger.debug ("Resolved classpath location [" + Location + "] to" + result); 
  } return
    Result.toarray (new Resource[result.size ());
}

In fact, the core is dofindallclasspathresources, which scans all the data in the path, and the function body is as follows:

Protected set Dofindallclasspathresources (String path) throws IOException {
    set result= new Linkedhashset<> ( );
    ClassLoader cl = getClassLoader ();
    Enumeration resourceurls = (cl!= null? Cl.getresources (PATH): classloader.getsystemresources (path));
    while (Resourceurls.hasmoreelements ()) {
        URL url = resourceurls.nextelement ();
        Result.add (Convertclassloaderurl (URL));
    }
    if ("". Equals (Path)) {
        //If the path is empty, all jar packages are found, added to result (the function is no longer in depth)
        addallclassloaderjarroots (cl, result);
    } return result
    ;
}

Important In this function: enumeration resourceurls = (CL!= null? Cl.getresources (PATH): classloader.getsystemresources (path)); That is, if the current class loader CL is not empty, call cl.getresources (path), and Cl is empty to use the System class loader to load, in fact cl.getresources (path) content is used is the parent delegation model (the current ClassLoader loading resources, If a parent loader exists, it is loaded with the parent loader.


2.3 If not beginning with classpath* and containing. or *

For example, find: Classpath:applicationcontext-*.xml, use function findpathmatchingresources, similar to 2.1 cases.

2.4 If it does not start with classpath* and does not contain. or *

For example find: Classpath:applicationcontext-test.xml, direct "Getresourceloader (). GetResource (Locationpattern)", That is, the direct use of the natural resource loader to load, where the default is to use Defaultresourceloader ().

Third, summary and test

Wrote a small test, the test code is as follows:

Private staticvoid output (String location) throws Exception {
    Resourcepatternresolver resourceloader = new Pathmatchingresourcepatternresolver ();
    resource[] Source = resourceloader.getresources (location);        System.out.println ("source.size:" + source.length);
    for (int i =0 i < source.length; i++) {
        Resource Resource = source[i];
        System.out.println (Resource);

    }

A number of test results are shown below:



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.