此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

资源

介绍

Java 的标准java.net.URL各种 URL 前缀的类和标准处理程序,不幸的是,对于对低级资源的所有访问来说,还不够。 为 例如,没有标准化的URL可用于访问需要从类路径或相对于ServletContext. 虽然可以为专用处理程序注册新的处理程序URLprefixes(类似于前缀的现有处理程序,例如http:),这通常是相当复杂,并且URL接口仍然缺少一些理想的功能,例如检查所指向资源是否存在的方法。spring-doc.cadn.net.cn

Resource接口

Spring的Resource界面位于org.springframework.core.io.package 是旨在成为一个功能更强大的接口,用于抽象对低级资源的访问。 这 以下列表概述了Resource接口。 请参阅Resourcejavadoc 了解更多详情。spring-doc.cadn.net.cn

public interface Resource extends InputStreamSource {

	boolean exists();

	boolean isReadable();

	boolean isOpen();

	boolean isFile();

	URL getURL() throws IOException;

	URI getURI() throws IOException;

	File getFile() throws IOException;

	ReadableByteChannel readableChannel() throws IOException;

	long contentLength() throws IOException;

	long lastModified() throws IOException;

	Resource createRelative(String relativePath) throws IOException;

	String getFilename();

	String getDescription();
}

作为Resource接口显示时,它扩展了InputStreamSource接口。 以下列表显示了InputStreamSource接口:spring-doc.cadn.net.cn

public interface InputStreamSource {

	InputStream getInputStream() throws IOException;
}

来自Resource接口是:spring-doc.cadn.net.cn

  • getInputStream():查找并打开资源,返回InputStream为 从资源中读取。预计每个调用都会返回一个新的InputStream. 调用方负责关闭流。spring-doc.cadn.net.cn

  • exists():返回一个boolean指示该资源是否实际存在于物理形式。spring-doc.cadn.net.cn

  • isOpen():返回一个boolean指示此资源是否代表句柄与开放流。 如果trueInputStream不能多次读取,并且必须只读取一次,然后关闭以避免资源泄漏。 返回false为 所有常用资源实现,但InputStreamResource.spring-doc.cadn.net.cn

  • getDescription():返回此资源的描述,用于处理错误使用资源时的输出。这通常是完全限定的文件名或资源的实际 URL。spring-doc.cadn.net.cn

其他方法可以让您获得实际的URLFile对象表示资源(如果底层实现兼容并支持功能)。spring-doc.cadn.net.cn

的一些实现Resource接口还实现了扩展的WritableResource接口 支持写入它的资源。spring-doc.cadn.net.cn

Spring 本身使用Resource抽象,作为参数类型许多方法签名。某些 Spring API 中的其他方法(例如构造函数到ApplicationContext实现)采取一个String以朴素或简单的形式用于创建Resource适合该上下文实现,或者通过Stringpath,让调用者指定特定的Resource必须创建和使用实现。spring-doc.cadn.net.cn

虽然Resource接口在 Spring 和 Spring 中被大量使用,它实际上是在您自己的代码中单独用作通用实用程序类非常方便,以便访问资源,即使您的代码不知道或关心 Spring 的任何其他部分。虽然这将您的代码与 Spring 耦合,但它实际上只是将其耦合到这一小部分实用程序类,它可以作为更强大的替代品URL并且可以是被认为等同于您为此目的使用的任何其他库。spring-doc.cadn.net.cn

Resource抽象不会取代功能。它会尽可能包装它。例如,一个UrlResource包装一个 URL 并使用URL做它的工作。

内置Resource实现

Spring 包括几个内置的Resource实现:spring-doc.cadn.net.cn

如需完整列表ResourceSpring 中可用的实现,请参阅“所有已知实现类”部分Resourcejavadoc 的文档。spring-doc.cadn.net.cn

UrlResource

UrlResource包装一个java.net.URL并且可用于访问任何对象通常可以通过 URL 访问,例如文件、HTTPS 目标、FTP 目标和 别人。 所有 URL 都有一个标准化的String表示形式,以便适当的标准化前缀用于指示一种 URL 类型与另一种 URL 类型。这包括file:用于访问文件系统路径,https:用于通过HTTPS 协议访问资源,ftp:用于通过 FTP 等访问资源。spring-doc.cadn.net.cn

一个UrlResource是由 Java 代码通过显式使用UrlResource构造 函数 但通常在调用 API 方法时隐式创建,该方法采用String参数表示路径。对于后一种情况,JavaBeansPropertyEditor最终决定哪种类型的Resource创建。如果路径字符串包含well-known (to property editor,即) 前缀(例如classpath:),它会创建一个适当的专业化Resource。但是,如果它无法识别前缀,它会假定该字符串是标准 URL 字符串,并创建一个UrlResource.spring-doc.cadn.net.cn

ClassPathResource

此类表示应从类路径获取的资源。它使用线程上下文类加载器、给定类加载器或给定类加载资源。spring-doc.cadn.net.cn

Resource实现支持解析为java.io.File如果类路径 资源驻留在文件系统中,但不适用于驻留在 jar 并且尚未扩展(通过 servlet 引擎或任何环境) 到文件系统。为了解决这个问题,各种Resource实现始终支持 resolution 作为java.net.URL.spring-doc.cadn.net.cn

一个ClassPathResource是由 Java 代码通过显式使用ClassPathResource构造函数,但通常在调用 API 方法时隐式创建,该方法采用String参数表示路径。对于后一种情况,JavaBeansPropertyEditor识别特殊前缀,classpath:,在字符串路径上,并且 创建一个ClassPathResource在这种情况下。spring-doc.cadn.net.cn

FileSystemResource

这是一个Resource实现java.io.File处理。它还支持java.nio.file.Pathhandles,应用 Spring 的标准基于 String 的路径 转换,但通过java.nio.file.Files应用程序接口。对于纯java.nio.path.Path基于支持使用PathResource相反。FileSystemResource支持分辨率作为File并作为URL.spring-doc.cadn.net.cn

PathResource

这是一个Resource实现java.nio.file.Path句柄, 执行所有 通过Path应用程序接口。它支持分辨率作为File和 作为URL并且还实现了扩展的WritableResource接口。PathResource实际上是一种纯粹的java.nio.path.Path基于替代FileSystemResource跟 不同createRelative行为。spring-doc.cadn.net.cn

ServletContextResource

这是一个Resource实现ServletContext解释 相关 Web 应用程序根目录中的相对路径。spring-doc.cadn.net.cn

它始终支持流访问和 URL 访问,但允许java.io.File仅访问权限 当 Web 应用程序存档被扩展并且资源物理上位于 文件系统。无论它是否被扩展并在文件系统上或被访问 直接从 JAR 或其他地方(如数据库(可以想象))实际上是 依赖于 Servlet 容器。spring-doc.cadn.net.cn

InputStreamResource

InputStreamResource是一个Resource给定的实现InputStream.它 仅当没有特定的Resource实施适用。在 特别,更喜欢ByteArrayResource或任何基于文件的Resource尽可能实现。spring-doc.cadn.net.cn

与其他Resource实现,这是 已打开的资源。因此,它返回trueisOpen().如果出现以下情况,请勿使用它 您需要将资源描述符保留在某个位置,或者如果您需要读取流 多次。spring-doc.cadn.net.cn

ByteArrayResource

这是一个Resource给定字节数组的实现。它创建了一个ByteArrayInputStream对于给定的字节数组。spring-doc.cadn.net.cn

它对于从任何给定的字节数组加载内容非常有用,而无需诉诸 一次性使用InputStreamResource.spring-doc.cadn.net.cn

ResourceLoader接口

ResourceLoader接口旨在由可以返回的对象实现 (即负载)Resource实例。以下列表显示了ResourceLoader接口定义:spring-doc.cadn.net.cn

public interface ResourceLoader {

	Resource getResource(String location);

	ClassLoader getClassLoader();
}

所有应用程序上下文都实现了ResourceLoader接口。因此,所有 应用程序上下文可用于获取Resource实例。spring-doc.cadn.net.cn

当您调用getResource()在特定应用程序上下文和位置路径上 specified 没有特定的前缀,则返回一个Resource类型,即 适合该特定应用程序上下文。例如,假设以下情况 代码片段针对ClassPathXmlApplicationContext实例:spring-doc.cadn.net.cn

Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
val template = ctx.getResource("some/resource/path/myTemplate.txt")

针对ClassPathXmlApplicationContext,则该代码返回ClassPathResource.如果 相同的方法针对FileSystemXmlApplicationContext例如,它会 返回一个FileSystemResource.对于一个WebApplicationContext,它将返回一个ServletContextResource.它同样会为每个上下文返回适当的对象。spring-doc.cadn.net.cn

因此,您可以以适合特定应用程序的方式加载资源 上下文。spring-doc.cadn.net.cn

另一方面,你也可以强制ClassPathResource无论 应用程序上下文类型,通过指定特殊的classpath:前缀,如下所示 示例显示:spring-doc.cadn.net.cn

Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
val template = ctx.getResource("classpath:some/resource/path/myTemplate.txt")

同样,您可以强制UrlResource通过指定任何标准来使用java.net.URL前缀。以下示例使用filehttps前缀:spring-doc.cadn.net.cn

Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
val template = ctx.getResource("file:///some/resource/path/myTemplate.txt")
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
val template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt")

下表总结了转换策略String对象设置为Resource对象:spring-doc.cadn.net.cn

表 1.资源字符串
前缀 示例 解释

类路径:spring-doc.cadn.net.cn

classpath:com/myapp/config.xmlspring-doc.cadn.net.cn

从类路径加载。spring-doc.cadn.net.cn

文件:spring-doc.cadn.net.cn

file:///data/config.xmlspring-doc.cadn.net.cn

加载为URL从文件系统。也可以看看FileSystemResource警告.spring-doc.cadn.net.cn

https:spring-doc.cadn.net.cn

https://myserver/logo.pngspring-doc.cadn.net.cn

加载为URL.spring-doc.cadn.net.cn

(无)spring-doc.cadn.net.cn

/data/config.xmlspring-doc.cadn.net.cn

取决于基础ApplicationContext.spring-doc.cadn.net.cn

ResourcePatternResolver接口

ResourcePatternResolver接口是ResourceLoader接口 它定义了解决位置模式的策略(例如,Ant 样式的路径 pattern) 变成Resource对象。spring-doc.cadn.net.cn

public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

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

如上所示,该接口还定义了一个特殊的classpath*:资源前缀 对于类路径中的所有匹配资源。请注意,资源位置为 在这种情况下,预计是一条没有占位符的路径——例如,classpath*:/config/beans.xml.JAR 文件或类路径中的不同目录可以 包含具有相同路径和相同名称的多个文件。有关更多详细信息,请参阅应用程序上下文构造函数资源路径中的通配符及其小节 在通配符支持上,使用classpath*:资源前缀。spring-doc.cadn.net.cn

一个传入的ResourceLoader(例如,通过ResourceLoaderAware语义)是否可以检查 它也实现了这个扩展接口。spring-doc.cadn.net.cn

PathMatchingResourcePatternResolver是一个可用的独立实现 在ApplicationContext并且也被ResourceArrayPropertyEditor为 填充Resource[]bean 属性。PathMatchingResourcePatternResolver能够 将指定的资源位置路径解析为一个或多个匹配的Resource对象。 源路径可以是与目标具有一对一映射的简单路径Resource,或者可以包含特殊的classpath*:前缀和/或内部 Ant 样式正则表达式(使用 Spring 的org.springframework.util.AntPathMatcher实用程序)。后者都有效 通配符。spring-doc.cadn.net.cn

默认值ResourceLoader在任何标准中ApplicationContext实际上是一个实例 之PathMatchingResourcePatternResolver它实现了ResourcePatternResolver接口。对于ApplicationContext实例本身,这也 实现ResourcePatternResolver接口,并将委托给默认的PathMatchingResourcePatternResolver.spring-doc.cadn.net.cn

ResourceLoaderAware接口

ResourceLoaderAwareinterface 是一个特殊的回调接口,用于识别 组件,这些组件希望提供ResourceLoader参考。以下列表 显示了ResourceLoaderAware接口:spring-doc.cadn.net.cn

public interface ResourceLoaderAware {

	void setResourceLoader(ResourceLoader resourceLoader);
}

当类实现ResourceLoaderAware并部署到应用程序上下文中 (作为 Spring 管理的 bean),它被识别为ResourceLoaderAware通过应用程序 上下文。然后,应用程序上下文调用setResourceLoader(ResourceLoader), 将自身作为参数提供(请记住,Spring 中的所有应用程序上下文都实现 这ResourceLoader接口)。spring-doc.cadn.net.cn

由于ApplicationContext是一个ResourceLoader,则 bean 还可以实现ApplicationContextAware接口,并直接使用提供的应用程序上下文来 加载资源。但是,一般来说,最好使用专门的ResourceLoader界面,如果这就是您所需要的。代码将仅与资源加载耦合 接口(可以被认为是一个实用程序接口),而不是整个 SpringApplicationContext接口。spring-doc.cadn.net.cn

在应用组件中,您还可以依赖于ResourceLoader如 实现ResourceLoaderAware接口。传统的 constructorbyType自动布线模式(如自动布线协作者中所述) 能够提供ResourceLoader对于构造函数参数或 setter 方法参数。为了获得更大的灵活性(包括能够 autowire 字段和多个参数方法),请考虑使用基于注释的 自动接线功能。在这种情况下,ResourceLoader自动连接到字段中, 构造函数参数或方法参数,该参数需要ResourceLoader类型为 long 由于相关字段、构造函数或方法携带@Autowired注解。 有关更多信息,请参阅@Autowired.spring-doc.cadn.net.cn

加载一个或多个Resource包含通配符的资源路径的对象 或利用特殊的classpath*:resource 前缀,请考虑使用ResourcePatternResolver自动连接到您的 应用程序组件而不是ResourceLoader.

资源作为依赖项

如果 bean 本身要通过某种方式确定和提供资源路径 动态进程的 bean 使用ResourceLoaderResourcePatternResolver接口来加载资源。例如,考虑负载 某种模板的模板,其中所需的特定资源取决于 用户的角色。如果资源是静态的,那么消除使用ResourceLoader接口(或ResourcePatternResolverinterface)完全,则具有 bean 公开了Resource它需要的属性,并期望它们被注入其中。spring-doc.cadn.net.cn

注入这些属性变得微不足道的是,所有应用程序上下文 注册并使用特殊的 JavaBeansPropertyEditor,可以转换String路径 自Resource对象。例如,以下内容MyBean类有一个template类型的属性Resource.spring-doc.cadn.net.cn

public class MyBean {

	private Resource template;

	public setTemplate(Resource template) {
		this.template = template;
	}

	// ...
}
class MyBean(var template: Resource)

在 XML 配置文件中,template属性可以使用简单的 string,如以下示例所示:spring-doc.cadn.net.cn

<bean id="myBean" class="example.MyBean">
	<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>

请注意,资源路径没有前缀。因此,由于应用程序上下文 本身将用作ResourceLoader,则资源通过ClassPathResource一个FileSystemResourceServletContextResource根据 应用程序上下文的确切类型。spring-doc.cadn.net.cn

如果您需要强制执行特定的Resourcetype 时,可以使用前缀。这 以下两个示例演示如何强制ClassPathResourceUrlResource(这 后者用于访问文件系统中的文件):spring-doc.cadn.net.cn

<property name="template" value="classpath:some/resource/path/myTemplate.txt">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>

如果MyBean类被重构以用于注释驱动的配置,则 路径到myTemplate.txt可以存储在名为template.path——例如, 在提供给 Spring 的属性文件中Environment(参见环境抽象)。然后可以通过@Value使用属性占位符进行注释(请参阅@Value).Spring会 将模板路径的值检索为字符串,并将特殊PropertyEditor将 将字符串转换为Resource对象要注入到MyBean构造 函数。 以下示例演示了如何实现此目的。spring-doc.cadn.net.cn

@Component
public class MyBean {

	private final Resource template;

	public MyBean(@Value("${template.path}") Resource template) {
		this.template = template;
	}

	// ...
}
@Component
class MyBean(@Value("\${template.path}") private val template: Resource)

如果我们想支持在多个 类路径中的位置——例如,在类路径中的多个 jar 中——我们可以 使用特殊的classpath*:前缀和通配符来定义templates.pathkey 作为classpath*:/config/templates/*.txt.如果我们重新定义MyBeanclass 如下所示, Spring 会将模板路径模式转换为Resource对象 可以注入MyBean构造 函数。spring-doc.cadn.net.cn

@Component
public class MyBean {

	private final Resource[] templates;

	public MyBean(@Value("${templates.path}") Resource[] templates) {
		this.templates = templates;
	}

	// ...
}
@Component
class MyBean(@Value("\${templates.path}") private val templates: Resource[])

应用程序上下文和资源路径

本节介绍如何使用资源(包括快捷方式)创建应用程序上下文 与 XML 一起使用、如何使用通配符和其他详细信息。spring-doc.cadn.net.cn

构造应用程序上下文

应用程序上下文构造函数(通常适用于特定的应用程序上下文类型) 将字符串或字符串数组作为资源的位置路径,例如 构成上下文定义的 XML 文件。spring-doc.cadn.net.cn

当这样的位置路径没有前缀时,特定的Resource类型构建自 该路径并用于加载 bean 定义取决于并且适用于 具体应用上下文。例如,请考虑以下示例,该示例创建了ClassPathXmlApplicationContext:spring-doc.cadn.net.cn

ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
val ctx = ClassPathXmlApplicationContext("conf/appContext.xml")

Bean 定义是从类路径加载的,因为ClassPathResource是 使用。但是,请考虑以下示例,该示例会创建FileSystemXmlApplicationContext:spring-doc.cadn.net.cn

ApplicationContext ctx =
	new FileSystemXmlApplicationContext("conf/appContext.xml");
val ctx = FileSystemXmlApplicationContext("conf/appContext.xml")

现在,Bean 定义从文件系统位置加载(在本例中,相对于 当前工作目录)。spring-doc.cadn.net.cn

请注意,使用特殊的classpath前缀或标准 URL 前缀 位置路径覆盖默认类型Resource创建以加载 bean 定义。请考虑以下示例:spring-doc.cadn.net.cn

ApplicationContext ctx =
	new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml")

FileSystemXmlApplicationContext从类路径加载 Bean 定义。 但是,它仍然是一个FileSystemXmlApplicationContext.如果它随后用作ResourceLoader,任何无前缀的路径仍被视为文件系统路径。spring-doc.cadn.net.cn

构建ClassPathXmlApplicationContext实例 — 快捷方式

ClassPathXmlApplicationContext公开了许多构造函数以启用 方便的实例化。基本思想是你只能提供一个字符串数组 仅包含 XML 文件本身的文件名(不包含前导路径 信息),并提供Class.这ClassPathXmlApplicationContext然后派生 来自提供的类的路径信息。spring-doc.cadn.net.cn

考虑以下目录布局:spring-doc.cadn.net.cn

com/
  example/
    services.xml
    repositories.xml
    MessengerService.class

以下示例显示了如何ClassPathXmlApplicationContext实例由 在名为services.xmlrepositories.xml(这些在 classpath)可以实例化:spring-doc.cadn.net.cn

ApplicationContext ctx = new ClassPathXmlApplicationContext(
	new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.xml"), MessengerService::class.java)

请参阅ClassPathXmlApplicationContextjavadoc 以获取有关各种构造函数的详细信息。spring-doc.cadn.net.cn

应用程序上下文构造函数资源路径中的通配符

应用程序上下文构造函数值中的资源路径可以是简单路径(如 前面显示),每个目标都有一对一的映射Resource或 或者,可以包含特殊的classpath*:前缀或内部 Ant 样式模式 (通过使用 Spring 的PathMatcher实用程序)。后者都有效 通配符。spring-doc.cadn.net.cn

此机制的一个用途是当您需要进行组件样式的应用程序组装时。都 组件可以将上下文定义片段发布到已知的位置路径,并且, 当使用前缀为classpath*:,则自动拾取所有组件片段。spring-doc.cadn.net.cn

请注意,此通配符特定于在应用程序上下文中使用资源路径 构造函数(或者当您使用PathMatcher实用程序类层次结构)并且是 在施工时解决。它与Resource类型本身。 您不能使用classpath*:前缀来构造实际的Resource如 资源一次仅指向一个资源。spring-doc.cadn.net.cn

Ant式图案

路径位置可以包含 Ant 样式模式,如以下示例所示:spring-doc.cadn.net.cn

/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml

当路径位置包含 Ant 样式模式时,解析器会遵循更复杂的模式 尝试解析通配符的过程。它会产生一个Resource对于通往 最后一个非通配符段,并从中获取 URL。如果此 URL 不是jar:URL 或 特定于容器的变体(例如zip:在 WebLogic 中,wsjar在 WebSphere 中,依此类推), 一个java.io.File从中获取,并用于通过遍历 文件系统。对于 jar URL,解析器要么获得java.net.JarURLConnection或手动解析 jar URL,然后遍历 用于解析通配符的 jar 文件的内容。spring-doc.cadn.net.cn

对便携性的影响

如果指定的路径已经是fileURL(隐式的,因为基ResourceLoader是文件系统之一或显式),通配符保证 以完全便携的方式工作。spring-doc.cadn.net.cn

如果指定的路径是classpath位置,解析器必须获取最后一个 非通配符路径段 URL,方法是将Classloader.getResource()叫。既然如此 只是路径的一个节点(不是末尾的文件),它实际上是未定义的(在ClassLoaderjavadoc)在这种情况下返回的 URL 类型。在实践中, 它始终是一个java.io.File表示目录(其中 ClassPath 资源 解析为文件系统位置)或某种 jar URL(其中 classpath 资源 解析为 jar 位置)。尽管如此,此作仍存在可移植性问题。spring-doc.cadn.net.cn

如果为最后一个非通配符段获取了jar URL,则解析器必须能够 获取一个java.net.JarURLConnection或手动解析 jar URL,以便能够 遍历 jar 的内容并解析通配符。这在大多数环境中确实有效 但在其他方面失败,我们强烈建议资源的通配符解析 来自 jar 在依赖它之前,请在您的特定环境中进行彻底测试。spring-doc.cadn.net.cn

classpath*:前缀

在构造基于 XML 的应用程序上下文时,位置字符串可以使用 特殊classpath*:prefix,如以下示例所示:spring-doc.cadn.net.cn

ApplicationContext ctx =
	new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
val ctx = ClassPathXmlApplicationContext("classpath*:conf/appContext.xml")

此特殊前缀指定与给定名称匹配的所有类路径资源 必须获取(在内部,这基本上是通过调用ClassLoader.getResources(…​)),然后合并形成最终应用程序 上下文定义。spring-doc.cadn.net.cn

通配符类路径依赖于getResources()基础的方法ClassLoader.由于现在大多数应用程序服务器都提供自己的ClassLoader实现时,行为可能会有所不同,尤其是在处理 jar 文件时。一个 简单的测试,检查是否classpath*works 是使用ClassLoader从中加载文件 在类路径上的 jar 中:getClass().getClassLoader().getResources("<someFileInsideTheJar>").尝试此测试 具有相同名称但位于两个不同位置的文件,例如,文件 具有相同的名称和相同的路径,但在类路径上的不同 jar 中。如果 返回不适当的结果,请检查应用程序服务器文档中的设置 这可能会影响ClassLoader行为。

您还可以将classpath*:前缀加上PathMatcher模式 位置路径的其余部分(例如classpath*:META-INF/*-beans.xml).在这个 case 中,解决策略相当简单:AClassLoader.getResources()call 是 用于最后一个非通配符路径段,以获取 类加载器层次结构,然后,在每个资源中,相同的PathMatcher分辨率 前面描述的策略用于通配符子路径。spring-doc.cadn.net.cn

与通配符相关的其他说明

请注意classpath*:,当与Ant风格的图案结合使用时,仅有效 在模式启动之前至少有一个根目录,除非实际的 目标文件驻留在文件系统中。这意味着诸如classpath*:*.xml可能不会从 jar 文件的根目录中检索文件,而只能从 jar 文件的根目录中检索文件 来自扩展目录的根目录。spring-doc.cadn.net.cn

Spring 检索类路径条目的能力源自 JDK 的ClassLoader.getResources()方法,它仅返回 空字符串(表示要搜索的潜在根)。Spring 评估URLClassLoader运行时配置和java.class.pathjar 文件中的清单 同样,但这并不能保证会导致可移植行为。spring-doc.cadn.net.cn

扫描类路径包需要存在相应的目录 类路径中的条目。当您使用 Ant 构建 JAR 时,请不要激活files-onlyJAR 任务的开关。此外,基于安全性,类路径目录可能不会被公开 某些环境中的策略 — 例如,JDK 1.7.0_45 上的独立应用程序 和更高(这需要在清单中设置“Trusted-Library”。参见 stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources)。spring-doc.cadn.net.cn

在模块路径(Java Module System)上,Spring 的类路径扫描通常作为 预期。这里也强烈建议将资源放入专用目录, 避免上述搜索 JAR 文件根级别的可移植性问题。spring-doc.cadn.net.cn

Ant式图案classpath:不保证资源找到匹配项 resources 如果要搜索的根包在多个类路径位置可用。 请考虑以下资源位置示例:spring-doc.cadn.net.cn

com/mycompany/package1/service-context.xml

现在考虑一个 Ant 风格的路径,有人可能会使用它来尝试查找该文件:spring-doc.cadn.net.cn

classpath:com/mycompany/**/service-context.xml

此类资源可能仅存在于类路径中的一个位置,但当路径(例如 前面的示例用于尝试解决它,解析器在(第一个) 返回的 URL 由getResource("com/mycompany");.如果此基础包节点存在于 倍数ClassLoaderlocations,则所需的资源可能不存在于第一个 位置找到。因此,在这种情况下,您应该更喜欢使用classpath*:使用 相同的 Ant 样式模式,它搜索包含com.mycompany基本包:classpath*:com/mycompany/**/service-context.xml.spring-doc.cadn.net.cn

FileSystemResource警告

一个FileSystemResource未附加到FileSystemApplicationContext(那 是,当FileSystemApplicationContext不是实际的ResourceLoader) 款待 绝对路径和相对路径,如您所期望的那样。相对路径相对于 当前工作目录,而绝对路径相对于 文件系统。spring-doc.cadn.net.cn

但是,出于向后兼容性(历史)原因,当FileSystemApplicationContextResourceLoader.这FileSystemApplicationContext全部附着的力FileSystemResource实例 将所有位置路径视为相对路径,无论它们是否以前导斜杠开头。 在实践中,这意味着以下示例是等效的:spring-doc.cadn.net.cn

ApplicationContext ctx =
	new FileSystemXmlApplicationContext("conf/context.xml");
val ctx = FileSystemXmlApplicationContext("conf/context.xml")
ApplicationContext ctx =
	new FileSystemXmlApplicationContext("/conf/context.xml");
val ctx = FileSystemXmlApplicationContext("/conf/context.xml")

以下示例也是等价的(尽管它们作为一个不同是有意义的 大小写是相对的,另一个是绝对的):spring-doc.cadn.net.cn

FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("some/resource/path/myTemplate.txt");
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("some/resource/path/myTemplate.txt")
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("/some/resource/path/myTemplate.txt")

在实践中,如果您需要真正的绝对文件系统路径,则应避免使用 绝对路径与FileSystemResourceFileSystemXmlApplicationContext和 强制使用UrlResource通过使用file:URL 前缀。以下示例 展示如何做到这一点:spring-doc.cadn.net.cn

// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt")
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
ApplicationContext ctx =
	new FileSystemXmlApplicationContext("file:///conf/context.xml");
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml")