How does spring parse the wildcard path?

Source: Internet
Author: User
Tags addall readfile

In the spring configuration file, we often see a configuration path similar to this:
Java code
Classpath:/com/module/**/* SQL. xml

The system automatically loads xml files that comply with the path rules according to the configuration path.
Let us assume that you have implemented the following functions:
What do you do if you load a compliant xml file based on a wildcard path?

Let's take a look at a small example:
Java code
Import java. io. IOException;
 
Import org. springframework. core. io. Resource;
Import org. springframework. core. io. support. PathMatchingResourcePatternResolver;
Import org. springframework. core. io. support. ResourcePatternResolver;
 
Public class XMLManager {
 
Private String location = "classpath: *. xml ";
 
Public void readFile () throws IOException {
ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver ();
Resource [] source = resourceLoader. getResources (location );
For (int I = 0; I <source. length; I ++ ){
Resource resource = source [I];
System. out. println (resource. getFilename ());
 
}
}
 
Public static void main (String [] args ){
 
XMLManager m = new XMLManager ();
Try {
M. readFile ();
} Catch (IOException e ){
E. printStackTrace ();
}
}
}


Output result:
Java code
ApplicationContext. xml
Logback. xml
Menu_my.xml

Is it easy?
You only need to call the getResources method of PathMatchingResourcePatternResolver to implement the desired function.
Next, let's take a closer look at spring's source code PathMatchingResourcePatternResolver:
1. getResources Method
Java code
Public Resource [] getResources (String locationPattern) throws IOException {
Assert. notNull (locationPattern, "Location pattern must not be null ");
If (locationPattern. startsWith (CLASSPATH_ALL_URL_PREFIX )){
// 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 {
// All class path resources with the given name
Return findAllClassPathResources (locationPattern. substring (CLASSPATH_ALL_URL_PREFIX.length ()));
}
}
Else {
// Only look for a pattern after a prefix here
// (To not get fooled by a pattern symbol in a strange prefix ).
Int prefixEnd = locationPattern. indexOf (":") + 1;
If (getPathMatcher (). isPattern (locationPattern. substring (prefixEnd ))){
// A file pattern
Return findPathMatchingResources (locationPattern );
}
Else {
// A single resource with the given name
Return new Resource [] {getResourceLoader (). getResource (locationPattern )};
}
}
}

This method is mainly used to determine whether locationPattern contains wildcards. If it contains wildcards, The findPathMatchingResources method is called. If it does not contain wildcards, it does not need to be parsed.
2. findPathMatchingResources Method
Java code
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 <Resource> (16 );
For (Resource rootDirResource: rootDirResources ){
RootDirResource = resolveRootDirResource (rootDirResource );
If (isJarResource (rootDirResource )){
Result. addAll (doFindPathMatchingJarResources (rootDirResource, subPattern ));
}
Else if (rootDirResource. getURL (). getProtocol (). startsWith (ResourceUtils. URL_PROTOCOL_VFS )){
Result. addAll (VfsResourceMatchingDelegate. findMatchingResources (rootDirResource, subPattern, getPathMatcher ()));
}
Else {
Result. addAll (doFindPathMatchingFileResources (rootDirResource, subPattern ));
}
}
If (logger. isDebugEnabled ()){
Logger. debug ("Resolved location pattern [" + locationPattern + "] to resources" + result );
}
Return result. toArray (new Resource [result. size ()]);
}

Split locationPattern into two parts: rootDirPath and subPattern.
RootDirPath is the root directory path.
SubPattern is a sub-directory path matching rule string.
View All subdirectories in the root directory and obtain all subdirectories.
In the doFindPathMatchingFileResources (rootDirResource, subPattern) method
Then match the subPattern one by one based on the subdirectories.
3. doFindPathMatchingFileResources
Java code
Protected Set <Resource> doFindPathMatchingFileResources (Resource rootDirResource, String subPattern)
Throws IOException {
 
File rootDir;
Try {
RootDir = rootDirResource. getFile (). getAbsoluteFile ();
}
Catch (IOException ex ){
If (logger. isWarnEnabled ()){
Logger. warn ("Cannot search for matching files underneath" + rootDirResource +
"Because it does not correspond to a directory in the file system", ex );
}
Return Collections. emptySet ();
}
Return doFindMatchingFileSystemResources (rootDir, subPattern );
}

Jump to another method doFindMatchingFileSystemResources:
Java code
Protected Set <Resource> doFindMatchingFileSystemResources (File rootDir, String subPattern) throws IOException {
If (logger. isDebugEnabled ()){
Logger. debug ("Looking for matching resources in directory tree [" + rootDir. getPath () + "]");
}
Set <File> matchingFiles = retrieveMatchingFiles (rootDir, subPattern );
Set <Resource> result = new LinkedHashSet <Resource> (matchingFiles. size ());
For (File file: matchingFiles ){
Result. add (new FileSystemResource (file ));
}
Return result;
}

RetrieveMatchingFiles

Java code
Protected Set <File> retrieveMatchingFiles (File rootDir, String pattern) throws IOException {
If (! RootDir. exists ()){
// Silently skip non-existing directories.
If (logger. isDebugEnabled ()){
Logger. debug ("Skipping [" + rootDir. getAbsolutePath () + "] because it does not exist ");
}
Return Collections. emptySet ();
}
If (! RootDir. isDirectory ()){
// Complain louder if it exists but is no directory.
If (logger. isWarnEnabled ()){
Logger. warn ("Skipping [" + rootDir. getAbsolutePath () + "] because it does not denote a directory ");
}
Return Collections. emptySet ();
}
If (! RootDir. canRead ()){
If (logger. isWarnEnabled ()){
Logger. warn ("Cannot search for matching files underneath directory [" + rootDir. getAbsolutePath () +
"] Because the application is not allowed to read the directory ");
}
Return Collections. emptySet ();
}
String fullPattern = StringUtils. replace (rootDir. getAbsolutePath (), File. separator ,"/");
If (! Pattern. startsWith ("/")){
FullPattern + = "/";
}
FullPattern = fullPattern + StringUtils. replace (pattern, File. separator ,"/");
Set <File> result = new LinkedHashSet <File> (8 );
DoRetrieveMatchingFiles (fullPattern, rootDir, result );
Return result;
}

Call the recursive method:
DoRetrieveMatchingFiles
Java code
Protected void doRetrieveMatchingFiles (String fullPattern, File dir, Set <File> result) throws IOException {
If (logger. isDebugEnabled ()){
Logger. debug ("Searching directory [" + dir. getAbsolutePath () +
"] For files matching pattern [" + fullPattern + "]");
}
File [] dirContents = dir. listFiles ();
If (dirContents = null ){
If (logger. isWarnEnabled ()){
Logger. warn ("cocould not retrieve contents of directory [" + dir. getAbsolutePath () + "]");
}
Return;
}
For (File content: dirContents ){
String currPath = StringUtils. replace (content. getAbsolutePath (), File. separator ,"/");
If (content. isDirectory () & getPathMatcher (). matchStart (fullPattern, currPath + "/")){
If (! Content. canRead ()){
If (logger. isDebugEnabled ()){
Logger. debug ("Skipping subdirectory [" + dir. getAbsolutePath () +
"] Because the application is not allowed to read the directory ");
}
}
Else {
DoRetrieveMatchingFiles (fullPattern, content, result );
}
}
If (getPathMatcher (). match (fullPattern, currPath )){
Result. add (content );
}
}
}

 

This article is from goodscript"
 

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.