spring官网在线学习文档翻译2
2. Resources(计][环境] 资源;物力)
2.1. Introduction(介绍;引进;采用;入门;传入)
Java’s 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实现可以用来访问需要从类路径或相对于ServletContext获得的资源。虽然可以为专业注册新处理程序URL前缀(类似于现有的前缀,如http处理程序:),这通常是非常复杂的,和URL接口仍然缺乏一些可取的功能,比如一个方法来检查存在的资源被指出。
2.2. The Resource interface(Resource接口)
Spring’s 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:
-
资源接口的一些最重要的方法是:
-
getInputStream()
: locates and opens the resource, returning anInputStream
for reading from the resource. It is expected that each invocation returns a freshInputStream
. It is the responsibility of the caller to close the stream.- getInputStream():定位并打开资源,返回从资源读取的InputStream。预期每次调用都会返回一个新的InputStream。调用者负责关闭流。
-
exists()
: returns aboolean
indicating whether this resource actually exists in physical form.- exists():返回一个布尔值,指示该资源是否以物理形式实际存在。
-
isOpen()
: returns aboolean
indicating whether this resource represents a handle with an open stream. Iftrue
, theInputStream
cannot be read multiple times, and must be read once only and then closed to avoid resource leaks. Will befalse
for all usual resource implementations, with the exception ofInputStreamResource
.- isOpen():返回一个布尔值,指示该资源是否表示一个打开流的句柄。如果为真,则不能多次读取InputStream,必须只读取一次,然后关闭以避免资源泄漏。对于所有常见的资源实现,将为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.- getDescription():返回该资源的描述,用于处理该资源时的错误输出。这通常是资源的完全限定文件名或实际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或File对象(如果底层实现是兼容的,并且支持该功能)。
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实现的构造函数),把一个字符串在朴实或简单的形式是用来创建一个上下文的资源适当的实现,或通过特殊前缀字符串路径,允许调用者指定一个特定的资源实现必须创建和使用。
While the Resource
interface is used a lot with Spring and by Spring, it’s actually very useful to use as a general utility class by itself in your own code, for access to resources, even when your code doesn’t 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和Spring中经常使用资源接口,但是在您自己的代码中作为一个通用实用程序类来使用它来访问资源实际上是非常有用的,即使您的代码不知道或不关心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,并使用包装后的URL来完成其工作。
2.3. Built-in Resource implementations(内置的资源实现)
There are a number of Resource
implementations that come supplied straight out of the box in Spring:
- 在Spring中有很多直接开箱即用的资源实现:
2.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,可以用来访问通常通过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 doesn’t recognize the prefix, it will assume the this is just a standard URL string, and will create a UrlResource
.
- UrlResource是由Java代码使用UrlResource构造函数显式创建的,但通常是在调用API方法时隐式创建的,该API方法接受表示路径的字符串参数。对于后一种情况,JavaBeans PropertyEditor最终将决定创建哪种类型的资源。如果路径字符串包含一些众所周知的前缀(即classpath:),它将为该前缀创建一个适当的专用资源。但是,如果它不能识别前缀,它将假定this只是一个标准的URL字符串,并将创建一个URL
2.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.
- 这个类表示应该从类路径获取的资源。它使用线程上下文类装入器、给定的类装入器或给定的类装入资源。
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格式的解析。如果类路径资源驻留在文件系统中,但是对于驻留在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.
- ClassPathResource是由Java代码使用ClassPathResource构造函数显式创建的,但通常是在调用API方法时隐式创建的,该API方法接受表示路径的字符串参数。对于后一种情况,JavaBeans PropertyEditor将识别字符串路径上的特殊前缀classpath:,并在这种情况下创建ClassPathResource。
2.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的资源实现。文件句柄。它显然支持文件和URL格式的解析。
2.3.4. ServletContextResource
This is a Resource
implementation for ServletContext
resources, interpreting relative paths within the relevant web application’s 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 it’s expanded and on the filesystem like this, or accessed directly from the JAR or somewhere else like a DB (it’s conceivable) is actually dependent on the Servlet container.
- 这始终支持流访问和URL访问,但只允许java.io。当扩展web应用程序归档并且资源在文件系统上物理时进行文件访问。不管它是否像这样在文件系统上展开,或者直接从JAR或其他地方(比如DB)访问它,实际上都依赖于Servlet容器。
2.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.
- 给定InputStream的资源实现。只有在没有适用的特定资源实现时才应该使用此方法。特别是,尽可能使用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。如果需要将资源描述符保存在某个地方,或者需要多次读取流,则不要使用它。
2.3.6. ByteArrayResource
This is a Resource
implementation for a given byte array. It creates a ByteArrayInputStream
for the given byte array.
- 这是给定字节数组的资源实现。它为给定的字节数组创建ByteArrayInputStream。
It’s useful for loading content from any given byte array, without having to resort to a single-use InputStreamResource
.
- 它用于从任何给定的字节数组加载内容,而不必求助于一次性使用的InputStreamResource。
2.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 doesn’t 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, you’d get back a FileSystemResource
. For a WebApplicationContext
, you’d get back a ServletContextResource
, and so on.
- 返回的是ClassPathResource;如果对FileSystemXmlApplicationContext实例执行相同的方法,则返回一个FileSystemResource。对于WebApplicationContext,你会得到一个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:
- 另一方面,你也可以强制ClassPathResource被使用,不管应用程序的上下文类型是什么,通过指定特殊的classpath:前缀:
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 String
s to Resource
s:
- 类似地,我们可以通过指定任何标准的java.net.URL前缀来强制使用UrlResource:
Prefix | Example | Explanation |
---|---|---|
classpath: | classpath:com/myapp/config.xml |
Loaded from the classpath. |
file: | file:///data/config.xml |
Loaded as a URL , from the filesystem. [3] |
http: | http://myserver/logo.png |
Loaded as a URL . |
(none) | /data/config.xml |
Depends on the underlying ApplicationContext . |
2.5. The ResourceLoaderAware interface(接口)
The ResourceLoaderAware
interface is a special marker interface, identifying objects that expect to be provided with a ResourceLoader
reference.
- ResourceLoaderAware接口是一个特殊的标记接口,用于标识期望通过ResourceLoader引用提供的对象。
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, it’s better to use the specialized ResourceLoader
interface if that’s all that’s 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.
- 当然,由于ApplicationContext是一个ResourceLoader, bean也可以实现ApplicationContext taware接口,并直接使用提供的应用程序上下文来加载资源,但是一般来说,如果只需要这么做的话,最好使用专门的ResourceLoader接口。代码将仅仅耦合到资源加载接口,可以将其视为一个实用程序接口,而不是整个Spring ApplicationContext接口。
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 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 @Autowired.
- 从spring2.5开始,你可以依靠ResourceLoader的自动装配来实现ResourceLoaderAware接口。“传统的”构造函数和byType自动装配模式(正如在自动装配协作器中描述的那样)现在能够分别为构造函数参数或setter方法参数提供类型ResourceLoader的依赖。为了获得更大的灵活性(包括自动装配字段和多个参数方法的能力),考虑使用新的基于注解的自动装配特性。在这种情况下,只要所讨论的字段、构造函数或方法带有@Autowired注解,ResourceLoader就会自动被导入期望ResourceLoader类型的字段、构造函数或方法参数。更多信息,请参见@Autowired。
2.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本身要通过某种动态过程来确定和提供资源路径,那么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,它可以将字符串路径转换为资源对象,这使得注入这些属性变得很简单。因此,如果myBean有一个类型为Resource的模板属性,它可以为该资源配置一个简单的字符串,如下所示:
<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,资源本身将加载通过ClassPathResource FileSystemResource或ServletContextResource(适当地)根据上下文的具体类型。
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).
- 如果需要强制使用特定的资源类型,那么可以使用前缀。下面两个示例展示了如何强制使用ClassPathResource和UrlResource(后者用于访问文件系统文件)。
<property name="template" value="classpath:some/resource/path/myTemplate.txt">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
2.7. Application contexts and Resource paths(应用程序上下文和资源路径)
2.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 doesn’t 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定义将从类路径加载,因为将使用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
…
- 注意,在位置路径上使用特殊的类路径前缀或标准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 aResourceLoader
, any unprefixed paths will still be treated as filesystem paths.- 将实际从类路径加载它的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…
- 由“服务”中定义的bean组成的ClassPathXmlApplicationContext实例。xml和dao。xml'可以像这样实例化…
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
Please do consult the ClassPathXmlApplicationContext
javadocs for details on the various constructors.
- :请参考ClassPathXmlApplicationContext javadocs以获得关于各种构造函数的详细信息。
2.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 Spring’s PathMatcher
utility). Both of the latter are effectively wildcards
- 应用程序上下文构造函数值中的资源路径可能是一个简单的路径(如上所示),它与目标资源有一对一的映射,或者可能包含特殊的“classpath*:”前缀和/或内部ant样式的正则表达式(使用Spring的PathMatcher实用程序匹配)。后者都是有效的通配符
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.
- 此机制的一个用途是在进行组件样式的应用程序组装时。所有组件都可以“发布”上下文定义片段到一个众所周知的位置路径,当最终的应用程序上下文使用相同的路径创建时,所有的组件片段都将被自动获取。
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. It’s 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
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不是jar: URL或特定容器的变体(例如:zip在WebLogic中,wsjar在WebSphere中,等等),那么是java.io。文件从中获取,并通过遍历文件系统来解析通配符。对于jar URL,解析器要么从中获取一个java.net.JarURLConnection,要么手动解析jar URL,然后遍历jar文件的内容以解析通配符。
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是一个文件系统URL),那么可以保证通配符以完全可移植的方式工作。
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.
- 如果指定的路径是类路径位置,那么解析器必须通过Classloader.getResource()调用获得最后一个非通配符路径段URL。因为这只是路径的一个节点(而不是最后的文件),所以实际上没有定义(在类加载器javadocs中)在本例中返回的是哪种类型的URL。实际上,它总是一个java.io。表示目录的文件,其中类路径资源解析为文件系统位置,或类路径资源解析为jar位置的某种类型的jar URL。不过,这个操作还有一个可移植性问题。
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.
- 如果获得了最后一个非通配符段的jar URL,那么解析器必须能够从中获得一个java.net.JarURLConnection,或者手动解析jar URL,以便能够遍历jar的内容并解析通配符。这在大多数环境中都可以工作,但在其他环境中会失败,强烈建议在依赖于jar资源的通配符解析之前,在您的特定环境中彻底测试它。
The classpath*: prefix(:前缀
When constructing an XML-based application context, a location string may use the special classpath*:
prefix:
- 当构造基于xml的应用程序上下文时,位置字符串可能使用特殊的类路径*:前缀:
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.
- 这个特殊的前缀指定必须获得与给定名称匹配的所有类路径资源(在内部,这本质上是通过ClassLoader.getResources(…)调用发生的),然后合并形成最终的应用程序上下文定义。
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. |
|
---|---|
- 通配符类路径依赖于基础类加载器的getResources()方法。由于大多数应用程序服务器现在都提供它们自己的类加载器实现,所以在处理jar文件时,行为可能会有所不同。检查classpath*是否工作的一个简单测试是使用类加载器从类路径的jar中加载一个文件: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:前缀还可以与路径匹配器模式结合在位置路径的其余部分,例如classpath:META-INF/*-beans.xml。在这种情况下,解决策略是相当简单的:一个ClassLoader.getResources()调用使用最后non-wildcard路径段得到所有匹配资源的类装入器层次结构,然后从每个资源上述相同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
might not retrieve files from the root of jar files but rather only from the root of expanded directories.
- 请注意,classpath:与ant样式的模式结合使用时,在模式开始之前,只能可靠地在至少一个根目录下工作,除非实际的目标文件驻留在文件系统中。这意味着像classpath😗.xml这样的模式可能不会从jar文件的根目录检索文件,而只是从展开目录的根目录检索文件。
Spring’s ability to retrieve classpath entries originates from the JDK’s ClassLoader.getResources()
method which only returns file system locations for a passed-in empty string (indicating potential roots to search). Spring evaluates URLClassLoader
runtime configuration and the "java.class.path" manifest in jar files as well but this is not guaranteed to lead to portable behavior.
- Spring检索类路径条目的能力源于JDK的ClassLoader.getResources()方法,该方法只返回传入的空字符串的文件系统位置(指示要搜索的潜在根)。Spring评估URLClassLoader运行时配置和"java.class "。路径“在jar文件中也显示,但这不能保证导致可移植的行为。
The scanning of classpath packages requires the presence of corresponding directory entries in the classpath. When you build JARs with Ant, make sure that you do not activate the files-only switch of the JAR task. Also, classpath directories may not get exposed based on security policies in some environments, e.g. standalone apps on JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests; see http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).On JDK 9’s module path (Jigsaw), Spring’s classpath scanning generally works as expected. Putting resources into a dedicated directory is highly recommendable here as well, avoiding the aforementioned portability problems with searching the jar file root level. | |
---|---|
- 类路径包的扫描要求类路径中存在相应的目录项。当您使用Ant构建JAR时,请确保没有激活JAR任务的文件切换。另外,在某些环境中,基于安全策略,类路径目录可能不会暴露出来,例如JDK 1.7.0_45或更高版本的独立应用程序(需要在清单中设置“Trusted-Library”;见http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources)。在JDK 9的模块路径(Jigsaw)上,Spring的类路径扫描通常按预期工作。这里也高度推荐将资源放在专用目录中,以避免搜索jar文件根级别时出现的可移植性问题。
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样式模式:如果要搜索的根包在多个类路径位置中可用,那么资源就不能保证找到匹配的资源。这是因为诸如之类的资源
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.
- ,解析器将处理getResource("com/mycompany")返回的(第一个)URL;。如果此基包节点存在于多个类加载器位置中,则实际的最终资源可能不在下面。因此,在这种情况下,最好使用相同的ant样式的“' classpath*: '”,它将搜索所有包含根pac的类路径位置
2.7.3. FileSystemResource caveats(警告)
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.
- 没有附加到FileSystemApplicationContext的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:
- 然而,由于向后兼容性(历史上的)原因,当FileSystemApplicationContext是ResourceLoader时,这一点会改变。FileSystemApplicationContext只是强制所有附加的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.
- 在实践中,如果需要真正的绝对文件系统路径,最好放弃使用绝对路径与FileSystemResource / FileSystemXmlApplicationContext,只使用一个UrlResource,通过使用file: URL前缀。
// 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");
后续类容戳我^^
本文来自博客园,作者:六爻呈乾,转载请注明原文链接:https://www.cnblogs.com/ilycq/p/13748409.html