资源

介绍

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

界面Resource

Spring 的接口位于包中 旨在成为对低级资源的抽象访问的更强大的接口。这 下面的清单提供了该界面的概述。有关更多详细信息,请参阅 Resource javadoc。Resourceorg.springframework.core.io.Resourcespring-doc.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();
}

如接口的定义所示,它扩展了接口。下面的清单显示了接口的定义:ResourceInputStreamSourceInputStreamSourcespring-doc.cn

public interface InputStreamSource {

	InputStream getInputStream() throws IOException;
}

界面中一些最重要的方法是:Resourcespring-doc.cn

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

  • exists():返回一个 物理形式。booleanspring-doc.cn

  • isOpen():返回一个 tag,指示此资源是否表示句柄 与开放的流。如果 ,则不能多次读取 ,并且 必须只读取一次,然后关闭以避免资源泄漏。的返回 所有常用的资源实现,除了 .booleantrueInputStreamfalseInputStreamResourcespring-doc.cn

  • getDescription():返回此资源的说明,用于错误 output 来执行。这通常是完全限定的文件名或 资源的实际 URL。spring-doc.cn

其他方法允许您获取表示 资源(如果底层实现兼容并支持 功能)。URLFilespring-doc.cn

该接口的某些实现还实现了扩展的 WritableResource 接口 对于支持写入它的资源。Resourcespring-doc.cn

Spring 本身广泛使用抽象,作为 需要资源时有许多方法签名。某些 Spring API 中的其他方法 (例如各种实现的构造函数)采用一个 THAT,它以朴素或简单的形式用于创建适当的 该上下文实现,或者通过路径上的特殊前缀,让 caller 指定必须创建和使用特定实现。ResourceApplicationContextStringResourceStringResourcespring-doc.cn

虽然该接口与 Spring 和 Spring 一起使用很多,但它实际上是 非常方便,可以在您自己的代码中单独用作通用工具类,以便访问 添加到资源中,即使您的代码不知道或不关心 Spring 的任何其他部分。 虽然这会将您的代码耦合到 Spring,但它实际上只将其耦合到这一小群 Utility 类,它可以作为 被认为等同于您用于此目的的任何其他库。ResourceURLspring-doc.cn

抽象不会取代功能。它将其包装在 可能。例如,a 包装一个 URL 并使用包装的 URL 来执行其 工作。ResourceUrlResourceURL

内置实现Resource

Spring 包括几个内置的实现:Resourcespring-doc.cn

有关 Spring 中可用的实现的完整列表,请查阅 Resource javadoc 的 “All Known Implementing Classes” 部分。Resourcespring-doc.cn

UrlResource

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

A 由 Java 代码显式使用构造函数创建 但通常在调用采用用于表示路径的参数的 API 方法时隐式创建。对于后一种情况,JavaBeans 最终决定创建哪种类型。如果路径字符串包含 众所周知的(对于属性编辑器来说,即)前缀(例如 ),它会创建一个 适当的 专门用于该前缀。但是,如果它无法识别 前缀,则假定该字符串是标准 URL 字符串,并创建一个 .UrlResourceUrlResourceStringPropertyEditorResourceclasspath:ResourceUrlResourcespring-doc.cn

ClassPathResource

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

此实现支持将 Expression 解析为 Bean 的 class path 资源驻留在文件系统中,但不适用于驻留在 jar 中,并且尚未扩展(通过 servlet 引擎或任何环境) 添加到文件系统中。为了解决这个问题,各种 implementations 始终支持 分辨率设置为 .Resourcejava.io.FileResourcejava.net.URLspring-doc.cn

A 是由 Java 代码通过显式使用构造函数创建的,但通常是在调用采用用于表示路径的参数的 API 方法时隐式创建的。对于后一种情况,JavaBeans 识别字符串路径上的特殊前缀 , 和 在这种情况下创建一个。ClassPathResourceClassPathResourceStringPropertyEditorclasspath:ClassPathResourcespring-doc.cn

FileSystemResource

这是 handles 的实现。它还支持句柄,应用 Spring 的标准基于 String 的 path 转换,但通过 API 执行所有操作。对于纯基础支持,请改用 a。 支持分辨率为 A 和 .Resourcejava.io.Filejava.nio.file.Pathjava.nio.file.Filesjava.nio.path.PathPathResourceFileSystemResourceFileURLspring-doc.cn

PathResource

这是一个用于 handles 的实现,执行所有 操作和转换。它支持将分辨率解析为 和 作为 A 进行,并且还实现了扩展接口。 实际上是 with 的纯基替代品 不同的行为。Resourcejava.nio.file.PathPathFileURLWritableResourcePathResourcejava.nio.path.PathFileSystemResourcecreateRelativespring-doc.cn

ServletContextResource

这是解释 相关 Web 应用程序根目录中的相对路径。ResourceServletContextspring-doc.cn

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

InputStreamResource

An 是给定 .它 仅当没有特定的实现适用时,才应使用。在 particular、prefer 或任何基于文件的实现(如果可能)。InputStreamResourceResourceInputStreamResourceByteArrayResourceResourcespring-doc.cn

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

ByteArrayResource

这是给定字节数组的实现。它为给定的字节数组创建一个。ResourceByteArrayInputStreamspring-doc.cn

它对于从任何给定的字节数组加载内容非常有用,而不必求助于 一次性使用。InputStreamResourcespring-doc.cn

界面ResourceLoader

该接口旨在由可以返回 (即 load)实例。下面的清单显示了接口定义:ResourceLoaderResourceResourceLoaderspring-doc.cn

public interface ResourceLoader {

	Resource getResource(String location);

	ClassLoader getClassLoader();
}

所有应用程序上下文都实现该接口。因此,所有 应用程序上下文可用于获取实例。ResourceLoaderResourcespring-doc.cn

当您调用特定的应用程序上下文时,位置路径 specified 没有特定的前缀,则返回一个 适合该特定应用程序上下文。例如,假设以下内容 针对实例运行的代码片段:getResource()ResourceClassPathXmlApplicationContextspring-doc.cn

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

对于 ,该代码返回一个 .如果 相同的方法对实例运行,它将 返回一个 .对于 a ,它将返回一个 .它同样会为每个上下文返回适当的对象。ClassPathXmlApplicationContextClassPathResourceFileSystemXmlApplicationContextFileSystemResourceWebApplicationContextServletContextResourcespring-doc.cn

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

另一方面,您也可以强制使用 application context 类型,通过指定特殊前缀,如下所示 示例显示:ClassPathResourceclasspath:spring-doc.cn

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

同样,您可以通过指定任何标准前缀来强制使用 a。以下示例使用 和 前缀:UrlResourcejava.net.URLfilehttpsspring-doc.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")

下表总结了将对象转换为对象的策略:StringResourcespring-doc.cn

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

类路径:spring-doc.cn

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

从 Classpath 加载。spring-doc.cn

文件:spring-doc.cn

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

作为 从文件系统加载。另请参阅 FileSystemResource 注意事项URLspring-doc.cn

https 的 URL 中:spring-doc.cn

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

加载为 .URLspring-doc.cn

(无)spring-doc.cn

/data/config.xmlspring-doc.cn

取决于底层 .ApplicationContextspring-doc.cn

界面ResourcePatternResolver

interface 是 interface 的扩展 ,它定义了解析位置模式(例如,Ant 样式路径 pattern) 转换为对象。ResourcePatternResolverResourceLoaderResourcespring-doc.cn

public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

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

从上面可以看出,这个接口还定义了一个特殊的资源前缀 对于类路径中的所有匹配资源。请注意,资源位置为 在本例中,应为不带占位符的路径 — 例如,.JAR 文件或类路径中的不同目录可以 包含多个具有相同路径和名称的文件。有关更多详细信息,请参阅 Application Context Constructor Resource Paths 及其子部分中的通配符 On 通配符支持,并带有 Resource 前缀。classpath*:classpath*:/config/beans.xmlclasspath*:spring-doc.cn

可以检查传入的 (例如,通过 ResourceLoaderAware 语义提供的) 它也实现了这个扩展接口。ResourceLoaderspring-doc.cn

PathMatchingResourcePatternResolver是可用的独立实现 在 an 和 之外也被用于 填充 bean 属性。 能够 将指定的资源位置路径解析为一个或多个匹配对象。 源路径可以是与 target 进行一对一映射的简单路径,也可以包含特殊前缀和/或 internal Ant 样式的正则表达式(使用 Spring 的实用程序进行匹配)。后者两者都是有效的 通配符。ApplicationContextResourceArrayPropertyEditorResource[]PathMatchingResourcePatternResolverResourceResourceclasspath*:org.springframework.util.AntPathMatcherspring-doc.cn

任何标准中的默认值实际上都是一个实例 其中实现接口。实例本身也是如此,它也 实现接口并委托给默认的 .ResourceLoaderApplicationContextPathMatchingResourcePatternResolverResourcePatternResolverApplicationContextResourcePatternResolverPathMatchingResourcePatternResolverspring-doc.cn

界面ResourceLoaderAware

该接口是一个特殊的回调接口,用于标识 组件。以下清单 显示了接口的定义:ResourceLoaderAwareResourceLoaderResourceLoaderAwarespring-doc.cn

public interface ResourceLoaderAware {

	void setResourceLoader(ResourceLoader resourceLoader);
}

当类实现并部署到应用程序上下文中时 (作为 Spring 管理的 bean)中,它被应用程序识别为 上下文。然后,应用程序上下文调用 , 将自身作为参数提供(请记住,Spring 中的所有应用程序上下文都实现了 界面)。ResourceLoaderAwareResourceLoaderAwaresetResourceLoader(ResourceLoader)ResourceLoaderspring-doc.cn

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

在应用程序组件中,您还可以依赖 as 的自动装配 实现接口的替代方法。传统模式和自动装配模式(如 自动装配协作者中所述) 能够为 constructor 参数或 setter 方法参数。为了获得更大的灵活性(包括 autowire fields 和多个参数方法),请考虑使用基于注释的 自动装配功能。在这种情况下,它被自动连接到一个字段 constructor 参数或期望类型为 long 的方法参数 因为有问题的 field、constructor 或 method 带有 Annotation。 有关更多信息,请参阅使用 @AutowiredResourceLoaderResourceLoaderAwareconstructorbyTypeResourceLoaderResourceLoaderResourceLoader@Autowiredspring-doc.cn

为包含通配符的资源路径加载一个或多个对象 或使用特殊的资源前缀,请考虑将 ResourcePatternResolver 的实例自动连接到您的 application 组件而不是 .Resourceclasspath*:ResourceLoader

作为依赖项的资源

如果 Bean 本身将通过某种排序来确定和提供资源路径 动态进程中,bean 使用 or 接口来加载资源可能是有意义的。例如,考虑 loading 中,所需的特定资源取决于 用户的角色。如果资源是静态的,那么完全消除接口(或接口)的使用是有意义的,让 bean 公开了它需要的属性,并期望将它们注入其中。ResourceLoaderResourcePatternResolverResourceLoaderResourcePatternResolverResourcespring-doc.cn

然后注入这些属性变得微不足道的是,所有应用程序上下文 注册并使用一个特殊的 JavaBeans ,它可以转换路径 到对象。例如,以下类具有 .PropertyEditorStringResourceMyBeantemplateResourcespring-doc.cn

public class MyBean {

	private Resource template;

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

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

在 XML 配置文件中,可以使用简单的 string 的 String,如下例所示:templatespring-doc.cn

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

请注意,资源路径没有前缀。因此,由于应用程序上下文 本身将用作 ,资源通过 、 、 或 、 加载,具体取决于 应用程序上下文的确切类型。ResourceLoaderClassPathResourceFileSystemResourceServletContextResourcespring-doc.cn

如果需要强制使用特定类型,可以使用前缀。这 以下两个示例展示了如何强制 A 和 A ( 后者用于访问文件系统中的文件):ResourceClassPathResourceUrlResourcespring-doc.cn

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

如果重构该类以用于注解驱动的配置,则 path to 可以存储在名为 — 例如 在 Spring 可用的属性文件中(参见Environment Abstraction)。然后,可以使用属性占位符通过注释引用模板路径(请参阅使用 @Value)。Spring会 将模板路径的值检索为字符串,并且会有一个特殊的 将字符串转换为要注入构造函数的对象。 以下示例演示了如何实现此目的。MyBeanmyTemplate.txttemplate.pathEnvironment@ValuePropertyEditorResourceMyBeanspring-doc.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)

如果我们想支持在多个 位置 — 例如,在 Classpath 的多个 jar 中 — 我们可以 使用特殊前缀和通配符将键定义为 。如果我们按如下方式重新定义类, Spring 会将模板路径模式转换为对象数组,这些对象 可以注入到构造函数中。classpath*:templates.pathclasspath*:/config/templates/*.txtMyBeanResourceMyBeanspring-doc.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.cn

构造应用程序上下文

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

当此类位置路径没有前缀时,从 该路径 和 用于加载 bean 定义的路径取决于 并且适合于 特定的应用程序上下文。例如,请考虑以下示例,该示例创建一个 :ResourceClassPathXmlApplicationContextspring-doc.cn

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

Bean 定义是从 Classpath 加载的,因为 使用。但是,请考虑以下示例,该示例创建一个 :ClassPathResourceFileSystemXmlApplicationContextspring-doc.cn

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

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

请注意,在 location path 覆盖 created 的默认类型以加载 bean 定义。请考虑以下示例:classpathResourcespring-doc.cn

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

Using 从 Classpath 中加载 bean 定义。 但是,它仍然是 .如果随后将其用作 a ,则任何未带前缀的路径仍被视为文件系统路径。FileSystemXmlApplicationContextFileSystemXmlApplicationContextResourceLoaderspring-doc.cn

构造实例 — 快捷方式ClassPathXmlApplicationContext

这公开了许多构造函数以启用 方便的实例化。基本思想是,您可以只提供一个字符串数组 ,仅包含 XML 文件本身的文件名(没有前导路径 信息),并提供 .then 派生 来自提供的类的路径信息。ClassPathXmlApplicationContextClassClassPathXmlApplicationContextspring-doc.cn

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

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

以下示例显示了由 在名为 和 (位于 classpath) 可以实例化:ClassPathXmlApplicationContextservices.xmlrepositories.xmlspring-doc.cn

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

有关各种构造函数的详细信息,请参见ClassPathXmlApplicationContext javadoc。spring-doc.cn

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

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

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

请注意,此通配符特定于应用程序上下文中资源路径的使用 构造函数(或者直接使用实用程序类层次结构时),并且是 在构建时解决。它与类型本身无关。 您不能使用前缀来构造实际的 ,因为 一个资源一次只指向一个资源。PathMatcherResourceclasspath*:Resourcespring-doc.cn

Ant-style 模式

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

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

当路径位置包含 Ant 样式模式时,解析程序遵循更复杂的 过程以尝试解析通配符。它为 path 生成一个 last 非通配符段并从中获取 URL。如果此 URL 不是 URL 或 特定于容器的变体(例如在 WebLogic、WebSphere 中等), a 从中获取,并用于通过遍历 文件系统。对于 jar URL,解析器要么从中获取 a,要么手动解析 jar URL,然后遍历 内容解析通配符。Resourcejar:zip:wsjarjava.io.Filejava.net.JarURLConnectionspring-doc.cn

对可移植性的影响

如果指定的路径已经是一个 URL(无论是隐式的,因为基是文件系统的 URL,还是显式的),则通配符保证为 以完全便携的方式工作。fileResourceLoaderspring-doc.cn

如果指定的路径是一个位置,则解析程序必须获取最后一个 非通配符路径段 URL。由于这个 只是路径的一个节点(而不是末尾的文件),实际上它未定义(在 javadoc 中)在这种情况下返回的 URL 类型。在实践中, 它始终表示目录(其中 Classpath 资源 解析为文件系统位置)或某种类型的 jar URL(其中 Classpath 资源 解析为 jar 位置)。尽管如此,此操作仍然存在可移植性问题。classpathClassloader.getResource()ClassLoaderjava.io.Filespring-doc.cn

如果获取了最后一个非通配符段的 jar URL,则解析程序必须能够 从中获取 a 或手动解析 jar URL,以便能够 遍历 jar 的内容并解析通配符。这在大多数环境中都有效 但在其他 API 中失败,我们强烈建议 resources 的通配符解析 来自 jars 在您依赖它之前,请在您的特定环境中对其进行全面测试。java.net.JarURLConnectionspring-doc.cn

前缀classpath*:

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

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

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

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

您还可以将前缀与 位置路径的其余部分(例如 )。在这个 的情况下,解析策略相当简单:调用 用于获取 类加载器层次结构,然后从每个资源中使用相同的分辨率 前面描述的策略用于通配符子路径。classpath*:PathMatcherclasspath*:META-INF/*-beans.xmlClassLoader.getResources()PathMatcherspring-doc.cn

与通配符相关的其他说明

请注意,当与 Ant 样式模式结合使用时,仅 可靠地使用至少一个根目录,除非实际的 目标文件驻留在文件系统中。这意味着诸如 jar 文件的根目录之类的模式可能不会从 jar 文件的根目录中检索文件,而只会从 从扩展目录的根目录。classpath*:classpath*:*.xmlspring-doc.cn

Spring 检索 Classpath 条目的能力源自 JDK 的方法,该方法仅返回 空字符串(指示要搜索的潜在根)。Spring 评估运行时配置和 jar 文件中的清单 ,但不能保证这会导致可移植行为。ClassLoader.getResources()URLClassLoaderjava.class.pathspring-doc.cn

扫描 classpath 包需要存在相应的目录 条目。使用 Ant 构建 JAR 时,请勿激活 JAR 任务的开关。此外,Classpath 目录可能不会根据安全性公开 某些环境中的策略 — 例如,JDK 1.7.0_45 上的独立应用程序 和更高级别(这需要在您的清单中设置 'Trusted-Library')。请参阅 stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources)。files-onlyspring-doc.cn

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

不保证包含资源的 ant 样式模式能够找到匹配项 resources(如果要搜索的根包在多个 Classpath 位置中可用)。 请考虑以下资源位置示例:classpath:spring-doc.cn

com/mycompany/package1/service-context.xml

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

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

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

FileSystemResource警告

A 未附加到 (该 is,当 a 不是实际的 ) 处理 绝对路径和相对路径。相对路径是相对于 当前工作目录,而绝对路径是相对于 文件系统。FileSystemResourceFileSystemApplicationContextFileSystemApplicationContextResourceLoaderspring-doc.cn

但是,出于向后兼容性(历史)原因,当 为 .强制所有附加的实例 将所有位置路径视为相对路径,无论它们是否以前导斜杠开头。 在实践中,这意味着以下示例是等效的:FileSystemApplicationContextResourceLoaderFileSystemApplicationContextFileSystemResourcespring-doc.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")

以下示例也是等效的(即使它们不同是有意义的,但作为一个 case 是相对的,另一个是绝对的):spring-doc.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")

在实践中,如果你需要真正的绝对文件系统路径,你应该避免使用 带有 OR 和 通过使用 URL 前缀强制使用 a。以下示例 演示如何执行此操作:FileSystemResourceFileSystemXmlApplicationContextUrlResourcefile:spring-doc.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")