【Spring】Spring Framework Reference Documentation中文版7

8. Resources

资源

 

8.1 Introduction

介绍

 

Javas standard java.net.URL class and standard handlers for various URL prefixes unfortunately are not quite adequate enough for all access to low-level resources. For example, there is no standardized URL implementation that may be used to access a resource that needs to be obtained from the classpath, or relative to a ServletContext. While it is possible to register new handlers for specialized URL prefixes (similar to existing handlers for prefixes such as http:), this is generally quite complicated, and the URL interface still lacks some desirable functionality, such as a method to check for the existence of the resource being pointed to.

Java标准的java.net.URL类和对于不同URL前缀的标准处理器不幸并不是充足的用于访问所有低级别的资源。例如,没有标准的URL实现可以用于访问从classpath中获得资源的需要,或相对于ServletContext。可以为特定的URL前缀注册新的处理器(类似于已经存在的处理器处理类似http:),这样比较方便并且URL接口依然缺少一些令人满意的功能,例如用于检测资源是否存在的方法。

 

8.2 The Resource interface

资源接口

 

Springs Resource interface is meant to be a more capable interface for abstracting access to low-level resources.

spring的资源接口希望是比较好的接口对于低级资源的抽象。

 

public interface Resource extends InputStreamSource {

 

    boolean exists();

 

    boolean isOpen();

 

    URL getURL() throws IOException;

 

    File getFile() throws IOException;

 

    Resource createRelative(String relativePath) throws IOException;

 

    String getFilename();

 

    String getDescription();

 

}

 

public interface InputStreamSource {

 

    InputStream getInputStream() throws IOException;

 

}

 

Some of the most important methods from the Resource interface are:

一些Resource接口中重要的方法是:

 

    getInputStream(): locates and opens the resource, returning an InputStream for reading from the resource. It is expected that each invocation returns a fresh InputStream. It is the responsibility of the caller to close the stream.

:定位和打开资源,返回读取资源的输入流。每次调用都会返回一个新的输入流。需要调用和关闭流。

    exists(): returns a boolean indicating whether this resource actually exists in physical form.

:返回一个boolean来暗示资源是否实际中存在。

    isOpen(): returns a boolean indicating whether this resource represents a handle with an open stream. If true, the InputStream cannot be read multiple times, and must be read once only and then closed to avoid resource leaks. Will be false for all usual resource implementations, with the exception of InputStreamResource.

:返回一个boolean暗示这个资源是否已经被一个打开的流在处理。如果是true,输入流不能读取多次并且必须读取一次然后关闭以防止资源泄漏。如果是false则所有正常的资源实现,除了InputStreamResource

    getDescription(): returns a description for this resource, to be used for error output when working with the resource. This is often the fully qualified file name or the actual URL of the resource.

:返回资源的描述,用于错误输出当使用资源时。通常是全限定文件名或资源的实际URL

 

Other methods allow you to obtain an actual URL or File object representing the resource (if the underlying implementation is compatible, and supports that functionality).

其他方法允许你获得一个实际的URL或文件object代表资源(如果潜在的实现是可用的,并且支持这些功能)。

 

The Resource abstraction is used extensively in Spring itself, as an argument type in many method signatures when a resource is needed. Other methods in some Spring APIs (such as the constructors to various ApplicationContext implementations), take a String which in unadorned or simple form is used to create a Resource appropriate to that context implementation, or via special prefixes on the String path, allow the caller to specify that a specific Resource implementation must be created and used.

资源抽象用于扩展spring自身,作为一个参数类型在许多方法签名中当方法需要资源时。其他方法在spring的一些api中(例如不同ApplicationContext实现的构造器参数),接收一个字符串或简单的形式用于创建Resource用于上下文的实现,或通过前缀在字符串路径中,允许调用特定的资源实现当创建和使用时。

 

While the Resource interface is used a lot with Spring and by Spring, its actually very useful to use as a general utility class by itself in your own code, for access to resources, even when your code doesnt know or care about any other parts of Spring. While this couples your code to Spring, it really only couples it to this small set of utility classes, which are serving as a more capable replacement for URL, and can be considered equivalent to any other library you would use for this purpose.

当通过spring大量使用Resource接口时,当作为一个普通的类时也很有用在你的代码中,用于访问资源,即使当你的代码不知道或关心spring的任何部分。这样你的代码和spring结合,只是和小部分类结合,可以用于替代URL并且和其他库相同,为了你要达到的目的。

 

It is important to note that the Resource abstraction does not replace functionality: it wraps it where possible. For example, a UrlResource wraps a URL, and uses the wrapped URL to do its work.

意识到资源抽象不会功能性的替代是重要的,他只是包装了一些必要的。例如,一个URLResource包装了URL,只要使用包装类就可以工作。

 

8.3 Built-in Resource implementations

内置的资源实现

 

There are a number of Resource implementations that come supplied straight out of the box in Spring:

spring的盒子外有有很多资源的实现:

 

8.3.1 UrlResource

 

The UrlResource wraps a java.net.URL, and may be used to access any object that is normally accessible via a URL, such as files, an HTTP target, an FTP target, etc. All URLs have a standardized String representation, such that appropriate standardized prefixes are used to indicate one URL type from another. This includes file: for accessing filesystem paths, http: for accessing resources via the HTTP protocol, ftp: for accessing resources via FTP, etc.

URLResource包装了java.net.URL,可以被用于访问任何obje通过URL,例如文件、HTTP目标、FTP目标等等。所有的URL有标准的字符串代表,例如标准的前缀用于暗示URL的类型区别于其他类型。包括file用于访问文件系统,http用于通过http协议来访问资源,ftp用于通过ftp访问资源等等。

 

A UrlResource is created by Java code explicitly using the UrlResource constructor, but will often be created implicitly when you call an API method which takes a String argument which is meant to represent a path. For the latter case, a JavaBeans PropertyEditor will ultimately decide which type of Resource to create. If the path string contains a few well-known (to it, that is) prefixes such as classpath:, it will create an appropriate specialized Resource for that prefix. However, if it doesnt recognize the prefix, it will assume the this is just a standard URL string, and will create a UrlResource.

使用URLResource构造器通过java代码创建一个URLResource,但是通常隐含的被创建当你调用API方法需要字符串参数意味着一个路径。最后一种情况,一个JavaBeans PropertyEditor将会最终决定创建什么类型的资源。如果字符串包含一个常见的前缀例如classpath,将会创建适当特定资源根据前缀。然而,如果没有识别出前缀,将会假设是一个标准的URL字符串后创建一个URLResource

 

8.3.2 ClassPathResource

 

This class represents a resource which should be obtained from the classpath. This uses either the thread context class loader, a given class loader, or a given class for loading resources.

这个类代表一个资源包含在classpath中。可以用于线程上下文类加载器、一个给定的类加载器或用于加载资源的给定类。

 

This Resource implementation supports resolution as java.io.File if the class path resource resides in the file system, but not for classpath resources which reside in a jar and have not been expanded (by the servlet engine, or whatever the environment is) to the filesystem. To address this the various Resource implementations always support resolution as a java.net.URL.

这个资源实现支持java.io.File如果类路径资源在文件系统中,但是不支持jar中的资源并且不能扩展(通过servlet引擎或环境因素)到文件系统。为了解决不同资源的实现也支持java.net.URL的处理。

 

A ClassPathResource is created by Java code explicitly using the ClassPathResource constructor, but will often be created implicitly when you call an API method which takes a String argument which is meant to represent a path. For the latter case, a JavaBeans PropertyEditor will recognize the special prefix classpath: on the string path, and create a ClassPathResource in that case.

通过java代码使用ClassPathResource的构造器来创建ClassPathResource,但是通常隐含的被创建当你调用API方法用字符串参数来代表一个路径。最后一种情况,JavaBeans PropertyEditor将会识别特定的前缀classpath,对于字符串路径并创建一个ClassPathResource

 

8.3.3 FileSystemResource

 

This is a Resource implementation for java.io.File handles. It obviously supports resolution as a File, and as a URL.

这是一个用于java.io.File处理的资源实现。他支持一个文件或一个URL的解决。

 

8.3.4 ServletContextResource

 

This is a Resource implementation for ServletContext resources, interpreting relative paths within the relevant web applications root directory.

这是一个用于ServletContext资源的实现,相对于web应用根路径来解析相对路径。

 

This always supports stream access and URL access, but only allows java.io.File access when the web application archive is expanded and the resource is physically on the filesystem. Whether or not its expanded and on the filesystem like this, or accessed directly from the JAR or somewhere else like a DB (its conceivable) is actually dependent on the Servlet container.

也支持流访问和URL访问,但是只允许java.io.File的访问当web应用打包是扩展的并且资源在文件系统中。不管是否扩展在文件系统中或直接从JAR中访问或其他的类似于DB也依赖于Servlet容器。

 

8.3.5 InputStreamResource

 

A Resource implementation for a given InputStream. This should only be used if no specific Resource implementation is applicable. In particular, prefer ByteArrayResource or any of the file-based Resource implementations where possible.

一个资源实现用于提供输入流。智能用于非特定资源的实现。特殊的情况,建议使用ByteArrayResource或任何一个基于文件的资源实现,如果可能的话。

 

In contrast to other Resource implementations, this is a descriptor for an already opened resource - therefore returning true from isOpen(). Do not use it if you need to keep the resource descriptor somewhere, or if you need to read a stream multiple times.

对比其他资源的实现,这是一个描述对于已经打开的资源——isOpen将返回true。如果你需要保留资源描述符的话或者多次读取一个流时不要使用它。

 

8.3.6 ByteArrayResource

 

This is a Resource implementation for a given byte array. It creates a ByteArrayInputStream for the given byte array.

这是一个支持字节数组的资源实现。根据给定的字节数组创建。

 

Its useful for loading content from any given byte array, without having to resort to a single-use InputStreamResource.

从给定字节数组中读取内容是有用的,而不需要求助于单一使用的InputStreamResource

 

8.4 The ResourceLoader

 

The ResourceLoader interface is meant to be implemented by objects that can return (i.e. load) Resource instances.

ResourceLoader接口意味着可以返回资源的实例。

 

public interface ResourceLoader {

 

    Resource getResource(String location);

 

}

 

All application contexts implement the ResourceLoader interface, and therefore all application contexts may be used to obtain Resource instances.

所有应用上下文实现ResourceLoader接口,所以所有应用上下文都一个使用来获得的资源的实例。

 

When you call getResource() on a specific application context, and the location path specified doesnt have a specific prefix, you will get back a Resource type that is appropriate to that particular application context. For example, assume the following snippet of code was executed against a ClassPathXmlApplicationContext instance:

当你调用getResource在特定的应用上下文,并且路径没有含有特定的前缀,你将会得到一个资源类型适合于特定的应用上下文。例如,例如下面的代码片段将会执行得到一个ClassPathXmlApplicationContext实例。

 

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

 

What would be returned would be a ClassPathResource; if the same method was executed against a FileSystemXmlApplicationContext instance, youd get back a FileSystemResource. For a WebApplicationContext, youd get back a ServletContextResource, and so on.

将会返回的是ClassPathResource:如果相同的方法被执行通过FileSystemXmlApplicationContext实例,你会得到一个FileSystemResource。对于一个web应用上下文,你会得到一个ServletContextResource

 

As such, you can load resources in a fashion appropriate to the particular application context.

通用,你可以加载资源以适当的方式通过特定的应用上下文。

 

On the other hand, you may also force ClassPathResource to be used, regardless of the application context type, by specifying the special classpath: prefix:

另一方面,你也可以强制使用ClassPathResource,不管应用上下文的类型,定义特定的classpath前缀:

 

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

 

Similarly, one can force a UrlResource to be used by specifying any of the standard java.net.URL prefixes:

相似的,你也可以强制使用UrlResource通过使用任意标准的java.net.URL前缀:

 

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

 

Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");

 

The following table summarizes the strategy for converting Strings to Resources:

下面的表格总结了将字符串转化为资源的策略

 

Table 8.1. Resource strings

资源字符串

Prefix

前缀

Example

示例

Explanation

解释

classpath:

classpath:com/myapp/config.xml

Loaded from the classpath.

classpath中加载

file:

file:///data/config.xml

Loaded as a URL, from the filesystem. [1]

从文件系统中加载作为一个URL

http:

http://myserver/logo.png

Loaded as a URL.

作为一个URL加载

(none)

/data/config.xml

Depends on the underlying ApplicationContext.

取决于潜在的应用上下文

[1] But see also Section 8.7.3, FileSystemResource caveats.

详情见8.7.3节,FileSystemResource说明。

 

8.5 The ResourceLoaderAware interface

ResourceLoaderAware接口

 

The ResourceLoaderAware interface is a special marker interface, identifying objects that expect to be provided with a ResourceLoader reference.

ResourceLoaderAware接口是一个特定的标注接口,定义objectResourceLoader引用来提供。

 

public interface ResourceLoaderAware {

 

    void setResourceLoader(ResourceLoader resourceLoader);

}

 

When a class implements ResourceLoaderAware and is deployed into an application context (as a Spring-managed bean), it is recognized as ResourceLoaderAware by the application context. The application context will then invoke the setResourceLoader(ResourceLoader), supplying itself as the argument (remember, all application contexts in Spring implement the ResourceLoader interface).

当一个类实现了ResourceLoaderAware并且部署在应用上下文中(作为一个spring管理的bean),将会被应用上下文识别为ResourceLoaderAware。应用上下文将会调用setResourceLoader(ResourceLoader),将其作为参数(记住,所有的应用上下文在spring中都实现了ResourceLoader接口)。

 

Of course, since an ApplicationContext is a ResourceLoader, the bean could also implement the ApplicationContextAware interface and use the supplied application context directly to load resources, but in general, its better to use the specialized ResourceLoader interface if thats all thats needed. The code would just be coupled to the resource loading interface, which can be considered a utility interface, and not the whole Spring ApplicationContext interface.

当然,每个应用上下文都是ResourceLoaderbean可以实现ApplicationContextAware接口然后使用提供的应用上下文直接来加载资源,但是通常情况,最好使用特定的ResourceLoader接口如果有这种需求。代码将和资源加载接口耦合,可以考虑为一个实用的接口,不是整个spirng应用上下文接口。

 

As of Spring 2.5, you can rely upon autowiring of the ResourceLoader as an alternative to implementing the ResourceLoaderAware interface. The "traditional" constructor and byType autowiring modes (as described in Section 7.4.5, Autowiring collaborators) are now capable of providing a dependency of type ResourceLoader for either a constructor argument or setter method parameter respectively. For more flexibility (including the ability to autowire fields and multiple parameter methods), consider using the new annotation-based autowiring features. In that case, the ResourceLoader will be autowired into a field, constructor argument, or method parameter that is expecting the ResourceLoader type as long as the field, constructor, or method in question carries the @Autowired annotation. For more information, see Section 7.9.2, @Autowired.

spring2.5中,你可以依赖资源加载器的自动注入代替实现ResourceLoaderAware接口。传统的构造器和通过类型注入的模式(在7.4.5节描述,自动加载处理)可以支持提供依赖ResourceLoader的类型作为一个构造器参数或set方法的参数。更加方便的(包括自动注入属性和多个参数方法),考虑使用新的基于注解的自动注入特性。在这种情况,ResourceLoader将会自动注入到属性、构造器参数或方法参数需要ResourceLoader类型的属性、构造器或方法在@Autowired注解。详见7.9.2@Autowired”。

 

8.6 Resources as dependencies

独立使用资源

 

If the bean itself is going to determine and supply the resource path through some sort of dynamic process, it probably makes sense for the bean to use the ResourceLoader interface to load resources. Consider as an example the loading of a template of some sort, where the specific resource that is needed depends on the role of the user. If the resources are static, it makes sense to eliminate the use of the ResourceLoader interface completely, and just have the bean expose the Resource properties it needs, and expect that they will be injected into it.

如果bean自身通过某些动态进程来决定和支持资源路径,这样会更有意义,通过使用ResourceLoader接口加载资源。考虑加载一些模板的例子,需要特定的资源依赖于用户的角色。如果资源是静态的,则完全使用ResourceLoader接口是有意义的,bean保留的他需要的资源属性然后将会被注入。

 

What makes it trivial to then inject these properties, is that all application contexts register and use a special JavaBeans PropertyEditor which can convert String paths to Resource objects. So if myBean has a template property of type Resource, it can be configured with a simple string for that resource, as follows:

然后注入这些属性是不重要的,所有的应用上下文注册和使用特定的JavaBeans PropertyEditor,可以将字符串路径转化为资源object。因此如果myBean有一个资源的template属性,可以按照如下简单的方式进行配置。

 

<bean id="myBean" class="...">

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

</bean>

 

Note that the resource path has no prefix, so because the application context itself is going to be used as the ResourceLoader, the resource itself will be loaded via a ClassPathResource, FileSystemResource, or ServletContextResource (as appropriate) depending on the exact type of the context.

注意资源没有前缀,因此因为应用上下文会被使用作为ResourceLoader,资源将会被加载,通过ClassPathResourceFileSystemResourceServletContextResource(适合的)依赖于上下文的类型。

 

If there is a need to force a specific Resource type to be used, then a prefix may be used. The following two examples show how to force a ClassPathResource and a UrlResource (the latter being used to access a filesystem file).

如果需要强制使用特定的资源,可以使用前缀。下面的例子展示了如果强制使用ClassPathResourceUrlResource(下面的被用于访问文件系统中的文件)

 

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

 

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

 

8.7 Application contexts and Resource paths

应用上下文和资源路径

 

8.7.1 Constructing application contexts

构造应用上下文

 

An application context constructor (for a specific application context type) generally takes a string or array of strings as the location path(s) of the resource(s) such as XML files that make up the definition of the context.

一个应用上下文构造器(对于特定的应用上下文类型)通常需要一个字符串或字符串数组作为本地资源的路径例如xml文件用于定义上下文。

 

When such a location path doesnt have a prefix, the specific Resource type built from that path and used to load the bean definitions, depends on and is appropriate to the specific application context. For example, if you create a ClassPathXmlApplicationContext as follows:

当路径没有前缀,特定的资源类型由路径来构建用于加载bean的定义,依赖于特定的应用上下文。例如,如果你如下一样创建了ClassPathXmlApplicationContext

 

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

 

The bean definitions will be loaded from the classpath, as a ClassPathResource will be used. But if you create a FileSystemXmlApplicationContext as follows:

bean的定义将会从classpath中加载,将会使用ClassPathResource。但是如果你如下创建了FileSystemXmlApplicationContext

 

ApplicationContext ctx =

    new FileSystemXmlApplicationContext("conf/appContext.xml");

 

The bean definition will be loaded from a filesystem location, in this case relative to the current working directory.

bean的定义将会从文件系统加载,取决于当前的工作路径。

 

Note that the use of the special classpath prefix or a standard URL prefix on the location path will override the default type of Resource created to load the definition. So this FileSystemXmlApplicationContext?

注意使用特定了classpath前缀或标准的URL前缀在路径上将会覆盖定义创建的默认的资源类型。因此这个FileSystemXmlApplicationContext

 

ApplicationContext ctx =

    new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");

 

    will actually load its bean definitions from the classpath. However, it is still a FileSystemXmlApplicationContext. If it is subsequently used as a ResourceLoader, any unprefixed paths will still be treated as filesystem paths.

实际会从classpath中加载bean的定义。然而,他依然是FileSystemXmlApplicationContext。如果使用了ResourceLoader,任何没有前缀的路径都会被作为是文件系统路径。

 

Constructing ClassPathXmlApplicationContext instances - shortcuts

构造ClassPathXmlApplicationContext实例 - 捷径

 

The ClassPathXmlApplicationContext exposes a number of constructors to enable convenient instantiation. The basic idea is that one supplies merely a string array containing just the filenames of the XML files themselves (without the leading path information), and one also supplies a Class; the ClassPathXmlApplicationContext will derive the path information from the supplied class.

ClassPathXmlApplicationContext暴露了一部分构造器允许方便的初始化。基本的方法是提供一个字符串数组包含xml文件的文件名(不需要指定路径信息),也支持一个类;ClassPathXmlApplicationContext将会从类中获取路径信息。

 

An example will hopefully make this clear. Consider a directory layout that looks like this:

一个例子可以很好的说明这件事。考虑一个如下的路径分布:

 

com/

  foo/

services.xml

daos.xml

    MessengerService.class

 

A ClassPathXmlApplicationContext instance composed of the beans defined in the 'services.xml' and 'daos.xml' could be instantiated like so?

ClassPathXmlApplicationContext实例由定义在services.xmldaos.xml中的bean定义组成可以像如下一样初始化?

 

ApplicationContext ctx = new ClassPathXmlApplicationContext(

    new String[] {"services.xml", "daos.xml"}, MessengerService.class);

 

Please do consult the ClassPathXmlApplicationContext javadocs for details on the various constructors.

详见ClassPathXmlApplicationContextjavadocs来查看不同的构造器信息。

 

8.7.2 Wildcards in application context constructor resource paths

应用上下文构造器资源路径中的通配符

 

The resource paths in application context constructor values may be a simple path (as shown above) which has a one-to-one mapping to a target Resource, or alternately may contain the special "classpath*:" prefix and/or internal Ant-style regular expressions (matched using Springs PathMatcher utility). Both of the latter are effectively wildcards

应用上下文构造器值的资源路径可以是简单路径(上面展示的)有一个一对一的对应指向目标资源,或者包含特定的classpath*:前缀或包含一个Ant分割的正则表达式(使用springPathMatcher工具处理)。后面都是有效的通配符。

 

One use for this mechanism is when doing component-style application assembly. All components can 'publish' context definition fragments to a well-known location path, and when the final application context is created using the same path prefixed via classpath*:, all component fragments will be picked up automatically.

当使用组件风格应用装配用于这个策略。所有组件可以发布上下文定义片段通过熟悉的路径,并且当最终的应用上下文被创建使用相同路径前缀通过classpath*:,所有组件的片段都会被自动使用。

 

Note that this wildcarding is specific to use of resource paths in application context constructors (or when using the PathMatcher utility class hierarchy directly), and is resolved at construction time. It has nothing to do with the Resource type itself. Its not possible to use the classpath*: prefix to construct an actual Resource, as a resource points to just one resource at a time.

注意通配符是特殊用于资源路径在应用上下文的构造器(或当使用直接的PathMatcher类),并且在构造时被处理。对资源本身不会做什么。不能使用classpath*:作为前缀来构造实际的资源,不能作为资源点指向一个资源。

 

Ant-style Patterns

Ant风格的模式

 

When the path location contains an Ant-style pattern, for example:

当路径包含Ant风格的模式,如下

 

/WEB-INF/*-context.xml

  com/mycompany/**/applicationContext.xml

  file:C:/some/path/*-context.xml

  classpath:com/mycompany/**/applicationContext.xml

 

The resolver follows a more complex but defined procedure to try to resolve the wildcard. It produces a Resource for the path up to the last non-wildcard segment and obtains a URL from it. If this URL is not a jar: URL or container-specific variant (e.g. zip: in WebLogic, wsjar in WebSphere, etc.), then a java.io.File is obtained from it and used to resolve the wildcard by traversing the filesystem. In the case of a jar URL, the resolver either gets a java.net.JarURLConnection from it or manually parses the jar URL and then traverses the contents of the jar file to resolve the wildcards.

解决方法有点复杂但是定义过程试图支持通配符。他从路径中生产一个资源取决于最后一个非通配符的片段并且从中获得一个URL。如果这个URL不是jarURL或包含特定的变量(例如zip:在WebLogicwsjarWebSphere中等等),从中获得一个java.io.File并且用于处理解决通配符通过该文件系统。防止是jarURL,处理器从中获得java.net.JarURLConnection或手动解析jarURL然后从其中解析通配符。

 

Implications on portability

可移植性的影响

 

If the specified path is already a file URL (either explicitly, or implicitly because the base ResourceLoader is a filesystem one, then wildcarding is guaranteed to work in a completely portable fashion.

如果特定的路径已经是一个文件的URL,因为基本的ResourceLoader是文件系统,通配符作为一种完全可移植的形式工作。

 

If the specified path is a classpath location, then the resolver must obtain the last non-wildcard path segment URL via a Classloader.getResource() call. Since this is just a node of the path (not the file at the end) it is actually undefined (in the ClassLoader javadocs) exactly what sort of a URL is returned in this case. In practice, it is always a java.io.File representing the directory, where the classpath resource resolves to a filesystem location, or a jar URL of some sort, where the classpath resource resolves to a jar location. Still, there is a portability concern on this operation.

如果特定的路径是classpath路径,那么解析器必须得到最后一个非通配符的路径片段URL通过Classloader.getResource()调用。自从这只是路径的一个节点(在最后不是文件)实际没有被定义(在ClassLoaderjavadocs中)将返回URL在这种情况下。在实际中,通常java.io.File代表一个路径,classpath资源处理一个文件系统位置或一个jarURL,如果classpath资源被解析为一个jar位置。而且,这种操作依然需要考虑可移植性。

 

If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to get a java.net.JarURLConnection from it, or manually parse the jar URL, to be able to walk the contents of the jar, and resolve the wildcard. This will work in most environments, but will fail in others, and it is strongly recommended that the wildcard resolution of resources coming from jars be thoroughly tested in your specific environment before you rely on it.

如果一个jarURL用于最后一个非通配符片段,解析器必须可以从中获得一个java.net.JarURLConnection或解析jarURL可以使用jar并解析通配符。在大部分环境中可以运行,但是在其他环境中会失败因此强烈推荐从jar中处理通配符并且经过测试在你实际使用的环境中。

 

The Classpath*: portability classpath*: prefix

 

When constructing an XML-based application context, a location string may use the special classpath*: prefix:

当构建一个基于xml的应用上下文,一个位置字符串可以使用特定的classpath*:前缀:

 

ApplicationContext ctx =

    new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");

 

This special prefix specifies that all classpath resources that match the given name must be obtained (internally, this essentially happens via a ClassLoader.getResources(?) call), and then merged to form the final application context definition.

特定的前缀定义了所有的classpath资源匹配给定的名字(内部必须通过调用ClassLoader.getResources),并且合并到最后应用上下文定义中。

 

[Note]

注意

 

The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar on the classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>"). Try this test with files that have the same name but are placed inside two different locations. In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.

通配符classpath依赖于类加载器中的getResources方法。作为大部分应用服务器现在支持他们自己的类加载器实现,行为是有区别的尤其是处理jar文件。一个简单的测试如果classpath*可以工作用于从jar中加载文件通过使用classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>")。尝试这样的测试需要同名但是替换两个不同的位置。为了防止返回不同的结果,检查应用服务器文档设置是否会影响类加载器的行为。

 

The classpath*: prefix can also be combined with a PathMatcher pattern in the rest of the location path, for example classpath*:META-INF/*-beans.xml. In this case, the resolution strategy is fairly simple: a ClassLoader.getResources() call is used on the last non-wildcard path segment to get all the matching resources in the class loader hierarchy, and then off each resource the same PathMatcher resolution strategy described above is used for the wildcard subpath.

classpath*前缀也可以组合通过PathMatcher模式在剩余的路径中,例如classpath*:META-INF/*-beans.xml。这个例子中,解决方法是很简单的:调用ClassLoader.getResources()用于最后一个无通配符的路径片段来获得所有匹配的资源在类加载器中,然后相同的PathMatcher解决策略用于通配符子路径。

 

Other notes relating to wildcards

其他有关通配符的注意事项

 

Please note that classpath*: when combined with Ant-style patterns will only work reliably with at least one root directory before the pattern starts, unless the actual target files reside in the file system. This means that a pattern like classpath*:*.xml will not retrieve files from the root of jar files but rather only from the root of expanded directories. This originates from a limitation in the JDKs ClassLoader.getResources() method which only returns file system locations for a passed-in empty string (indicating potential roots to search).

请注意classpath*:当和Ant风格的匹配一起使用时将可以工作至少一个根路径在模式开始之前,除非实际的目标文件在文件系统中。这意味着类似于classpath*:*.xml模式将不会从根的jar文件中读取而是从扩展根路径中读取。这起源于JDKClassLoader.getResources()方法的限制只能返回文件系统位置用于一个空的字符串(隐含需找的根路径)。

 

Ant-style patterns with classpath: resources are not guaranteed to find matching resources if the root package to search is available in multiple class path locations. This is because a resource such as

Ant风格的模式和classpath:资源融合不能简单匹配资源如果用于查找的根包在多个类路径中可用。这是因为资源是如下:

 

com/mycompany/package1/service-context.xml

 

may be in only one location, but when a path such as

 

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

 

is used to try to resolve it, the resolver will work off the (first) URL returned by getResource("com/mycompany");. If this base package node exists in multiple classloader locations, the actual end resource may not be underneath. Therefore, preferably, use " `classpath*:`" with the same Ant-style pattern in such a case, which will search all class path locations that contain the root package.

是需要处理的,处理器将会工作返回URL通过getResource("com/mycompany")。如果这个基本的包节点在多个类加载路径中存在,实际的资源不会在底层。因此,最好使用" `classpath*:`"Ant风格模式在这样的例子中,将会查找所有的类路径包含根包。

 

8.7.3 FileSystemResource caveats

FileSystemResource的警告

 

A FileSystemResource that is not attached to a FileSystemApplicationContext (that is, a FileSystemApplicationContext is not the actual ResourceLoader) will treat absolute vs. relative paths as you would expect. Relative paths are relative to the current working directory, while absolute paths are relative to the root of the filesystem.

FileSystemResource不是和FileSystemApplicationContext连在一起(因为FileSystemApplicationContext不是一个实际的ResourceLoader)将会按你的期望处理绝对路径和相对路径。相对路径相对于当前的工作路径,当绝对路径是相对于文件系统的根路径。

 

For backwards compatibility (historical) reasons however, this changes when the FileSystemApplicationContext is the ResourceLoader. The FileSystemApplicationContext simply forces all attached FileSystemResource instances to treat all location paths as relative, whether they start with a leading slash or not. In practice, this means the following are equivalent:

为了向后兼容(历史原因):FileSystemApplicationContextResourceLoaderFileSystemApplicationContext强制所有和FileSystemResource实例相关来处理所有路径不管他们是否以斜线开始。实际,这意味着下面是一样的:

 

ApplicationContext ctx =

    new FileSystemXmlApplicationContext("conf/context.xml");

 

ApplicationContext ctx =

    new FileSystemXmlApplicationContext("/conf/context.xml");

 

As are the following: (Even though it would make sense for them to be different, as one case is relative and the other absolute.)

如下(尽管他看起来是不同的,其中一个是相对的而另一个是绝对的)

 

FileSystemXmlApplicationContext ctx = ...;

ctx.getResource("some/resource/path/myTemplate.txt");

 

FileSystemXmlApplicationContext ctx = ...;

ctx.getResource("/some/resource/path/myTemplate.txt");

 

In practice, if true absolute filesystem paths are needed, it is better to forgo the use of absolute paths with FileSystemResource / FileSystemXmlApplicationContext, and just force the use of a UrlResource, by using the file: URL prefix.

实际中,绝对的文件系统路径是需要的,最好放弃使用绝对路径在FileSystemResourceFileSystemXmlApplicationContext,只是强制使用UrlResource通过使用URL前缀。

 

// actual context type doesn't matter, the Resource will always be UrlResource

// 实际上下文类型不重要,将会被当做UrlResource来处理

ctx.getResource("file:///some/resource/path/myTemplate.txt");

 

// force this FileSystemXmlApplicationContext to load its definition via a UrlResource

// 强制FileSystemXmlApplicationContextUrlResource中加载定义

ApplicationContext ctx =

    new FileSystemXmlApplicationContext("file:///conf/context.xml");

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值