(Spring中资源的加载Resource)默认加载全部配置文件*.properties

(Spring中资源的加载Resource)默认加载全部配置文件*.properties_第1张图片(Spring中资源的加载Resource)默认加载全部配置文件*.properties_第2张图片

默认加载全部的配置文件(完整代码路径:https://blog.csdn.net/zhaoyunfei1/article/details/97015274)

Spring中资源的加载是定义在ResourceLoader接口中的,它跟前面提到的抽象资源的关系如下:

(Spring中资源的加载Resource)默认加载全部配置文件*.properties_第3张图片

ResourceLoader的源码

package org.springframework.core.io;

import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;

public interface ResourceLoader {
    String CLASSPATH_URL_PREFIX = "classpath:";

    Resource getResource(String var1);

    @Nullable
    ClassLoader getClassLoader();
}

我们发现,其实ResourceLoader接口只提供了classpath前缀的支持。而classpath*的前缀支持是在它的子接口ResourcePatternResolver中。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.core.io.support;

import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

public interface ResourcePatternResolver extends ResourceLoader {
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

    Resource[] getResources(String var1) throws IOException;
}

 通过2个接口的源码对比,我们发现ResourceLoader提供 classpath下单资源文件的载入,而ResourcePatternResolver提供了多资源文件的载入。

Spring还提供了一种更强大的Ant模式通配符匹配,从能一个路径匹配一批资源。

        Ant路径通配符支持“?”、“*”、“**”,注意通配符匹配不包括目录分隔符“/”:

         “?”:匹配一个字符,如“config?.xml”将匹配“config1.xml”;

         “*”:匹配零个或多个字符串,如“cn/*/config.xml”将匹配“cn/javass/config.xml”,但不匹配匹配“cn/config.xml”;                                   而“cn/config-*.xml”将匹配“cn/config-dao.xml”;

         “**”:匹配路径中的零个或多个目录,如“cn/**/config.xml”将匹配“cn /config.xml”,也匹配“cn/javass/spring/config.xml”;                       而“cn/javass/config-**.xml”将匹配“cn/javass/config-dao.xml”,即把“**”当做两个“*”处理。

Spring提供AntPathMatcher来进行Ant风格的路径匹配。具体测试请参考cn.javass.spring.chapter4. AntPathMatcherTest。

ResourcePatternResolver有一个实现类:PathMatchingResourcePatternResolver,那我们直奔主题,查看PathMatchingResourcePatternResolver的getResources()

public Resource[] getResources(String locationPattern) throws IOException {
		Assert.notNull(locationPattern, "Location pattern must not be null");
		//是否以classpath*开头
		if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
			//是否包含?或者*
			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)};
			}
		}
	}

由此我们可以看出在加载配置文件时,以是否是以classpath*开头分为2大类处理场景,每大类在又根据路径中是否包括通配符分为2小类进行处理,

处理的流程图如下:

(Spring中资源的加载Resource)默认加载全部配置文件*.properties_第4张图片

分析到这,结合测试我们可以总结一下:
1.无论是classpath还是classpath*都可以加载整个classpath下(包括jar包里面)的资源文件。
2.classpath只会返回第一个匹配的资源,查找路径是优先在项目中存在资源文件,再查找jar包。
3.文件名字包含通配符资源(如果spring-*.xml,spring*.xml),   如果根目录为"", classpath加载不到任何资源, 而classpath*则可以加载到classpath中可以匹配的目录中的资源,但是不能加载到jar包中的资源
    

第1,2点比较好表理解,大家可以自行测试,第三点表述有点绕,举个例,现在有资源文件结构如下:

classpath:notice*.txt                                                               加载不到资源
classpath*:notice*.txt                                                            加载到resource根目录下notice.txt
classpath:META-INF/notice*.txt                                          加载到META-INF下的一个资源(classpath是加载到匹配的第一个资源,就算删除classpath下的notice.txt,他仍然可以                                                                                                  加载jar包中的notice.txt)
classpath:META-*/notice*.txt                                              加载不到任何资源
classpath*:META-INF/notice*.txt                                        加载到classpath以及所有jar包中META-INF目录下以notice开头的txt文件
classpath*:META-*/notice*.txt                                             只能加载到classpath下 META-INF目录的notice.txt

原文:https://blog.csdn.net/supportuat/article/details/50931311 

你可能感兴趣的:(JAVA基础)