Spring Official document translation--5. resources

Source: Internet
Author: User
Tags file url

5. Resources
5.1Introduction
Using the standard Java.net.URL class and various URL prefix processors does not satisfy our access to the underlying resources. For example, there is no standardized URL implementation class for accessing resources under classpath or relative to ServletContext. Although it is possible to register a new processor for a specific URL prefix (similar to an existing processor for the http: prefix), this is usually more complex, and the URL interface still lacks some useful methods, such as checking the existence of a resource.
5.2 ResourceInterface

Spring's resource interface is to abstract the access to the underlying resource to make it more appropriate:

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 in the resource interface are:

getInputStream (): locates and opens the resource, reads the resource, and returns a InputStream. Each call returns a new InputStream. The caller needs to close the resource manually.

exists (): returns the presence of the underlying resource that is currently represented

IsOpen (): True indicates that InputStream cannot be read multiple times and can only be read once and then closed to avoid resource leaks. For most resource implementations, the class returns false, except for Inputstreamresource.

getdescription (): Returns the descriptor of the underlying resource represented by the current resource, used when outputting an error when using the resource. This is usually the fully qualified class name or the actual URL of the resource.

The remaining methods allow you to obtain a real URL or file object that can represent the resource (if the underlying implementation is compatible and supports this method).

Resource's abstraction is widely applied to spring itself: when a resource is needed, resource is used as one of the parameters in many method signatures. Other methods of spring APIs, such as constructors for various ApplicationContext implementations, use a simple string to create a resource suitable for this context, or specify the type of resource based on a special prefix in the string.

Because the resource interface is widely used in spring. Maybe you don't care about the rest of spring, but you can apply it (Resource) as a generic tool class to your code to access resources. This is only a small part of the coupling, and these parts will completely replace the URL and provide additional functionality, you can completely think of it as any other third-party lib.

It is important to note that the resource abstraction does not replace the original function, but rather encapsulates a layer on its original basis. For example, Urlresource encapsulates a URL and then delegates the URL to work.


5.3built -inResourceImplement

Spring has built in some resource implementation classes for you to use:


Urlresource

The Urlresource encapsulates a java.net.URL that can be used to access any object that can be accessed with a URL, such as files, HTTP targets, FTP targets, and so on. All of these URLs have a standardized string representation, which allows you to use a prefix to indicate the type of the URL. File: Used to access the system path, http: Access to resources through the HTTP protocol, ftp: Access to resources through FTP, and so on.

Urlresource objects can be created using constructors, but are typically created using a string that represents a path. In the latter case, PropertyEditor will ultimately decide what kind of resource to create. If the string representing the path contains some well-known prefixes such as: classpath:, then a resource will be created that matches this prefix. However, if no prefix is found, it will be treated as a standard URL string, and then a urlresource is created.


Classpathresource

This class represents the resources obtained from the classpath. It uses the current thread context class loader, the specified class loader, or the specified class to load the resource.

If the CLASSPATH resource exists in the file system (excluding packaging in the jar), then Classpathresource also supports the use of java.io.File to resolve it. In addition, a variety of resource implementations always support the use of Java.net.URL to solve (of course, this is the bottom-level implementation, but it is convenient and troublesome relationship).

Classpathresource objects can be created using constructors, but are typically created using a string that represents a path. In the latter case, PropertyEditor will find the classpath: prefix and then create a classpathresource.


Filesystemresource

This resource implementation is intended to handle java.io.File, and it is clear that it is also supported with File or URL resolution.


Servletcontextresource

This is the implementation class that corresponds to the ServletContext resource and is able to parse the path relative to the Web application's root directory.

This class supports stream access and URL access, but only when the Web app is decompressed can it be accessed using Java.io.File. Whether or not the Web application is decompressed, or directly accessing the jar or somewhere else (such as db) is actually dependent on the servlet container.


Inputstreamresource

The resource implementation class for a specified inputstream. It is only used if no explicit resource implementation is available. Use Bytearrayresource or the rest of the file-based resource implementation classes as preferentially as possible.


Bytearrayresource

The resource implementation class that corresponds to a specified character array. It creates a bytearrayinputstream for the specified character array.

This class is useful when loading content from a specified array of characters. Because this eliminates the need to use the disposable inputstreamresource.


5.4 Resourceloader

The resource instance can be returned (that is, loaded) by implementing the Resourceloader interface.

Public interface Resourceloader {Resource getresource (String location);}

All application contexts implement the Resourceloader interface, so all application contexts can be used to obtain resource instances.

When you call the GetResource () method in a particular application context, if the resource path does not specify a prefix at this point, you will get a resource that is appropriate for the current application context. For example, suppose that the CTX in the following code fragment is Classpathxmlapplicationcontext:

Resource template = Ctx.getresource ("Some/resource/path/mytemplate.txt");

Then the return will be a classpathresource. And if the same method is called in Filesystemxmlapplicationcontext, then you will get a filesystemresource. If in Webapplicationcontext, then you will get a servletcontextresource.

So dependent, you can load resources according to the application context.

On the other hand, you can also force loading of classpathresource regardless of the type of application context, just by specifying the prefix "Classpath:" To:

Resource template = Ctx.getresource ("Classpath:some/resource/path/mytemplate.txt");

Similarly, you can specify a standard Java.net.URL prefix to force the loading of Urlresource:

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 string-to-resource conversion strategy (here)


5.5 ResourceloaderawareInterface

The Resourceloaderaware interface is a special markup interface that flags objects that want to get resourceloader references.

public interface Resourceloaderaware {void Setresourceloader (Resourceloader resourceloader);}

When a class implements the Resourceloaderaware interface and is deployed to the application context (such as a spring-managed bean), it is treated as resourceloaderaware by the application context. The application context then invokes its Setresourceloader (Resourceloader) method and provides itself as a parameter (remember that all application contexts in spring implement the Resourceloader interface).

Of course, because a applicationcontext is a resourceloader,bean can also implement Applicationcontextaware interface to load resources, but in general, if only the resources to load such a function, It is best to use a refined Resourceloader interface. Because of this, the code is only coupled to the interface loaded by the resource, which can be used as a tool interface instead of being coupled to the applicationcontext of the whole spring.

In spring 2.5, you can take advantage of automatic assembly without implementing the Resourceloaderaware interface. The "traditional" constructor and Bytype automatic assembly modes are all capable of providing resourceloader references. To be more flexible, including automatic assembly fields and multiple parameter methods, you can use automatic annotation-based assembly. In this case, the Resourceloader will be automatically assembled into fields with @autowired annotations, constructor parameters, or method parameters.


5.6 Resourcesas a dependency (inject resources)

If the bean itself is going to determine and provide a resource path in a dynamic way, it should use the Resourceloader interface to load the resource. For example, you need to load a template based on the user's role. If the resource is fixed, there is no need to use the Resourceloader interface, just let the bean expose the resource attribute and then inject it.

All application contexts register and use a special propertyeditor, which converts the string path to a resource object, which makes it easy to inject resource properties. So for example, Mybean has a template property of type resource, which can be injected with a simple string, such as:

<bean id= "Mybean" class= "..." ><property name= "template" value= "Some/resource/path/mytemplate.txt"/>


Note that this resource path does not have a prefix, and because the application context will be treated as resourceloader, the loaded resource will be determined based on the current application context type Classpathresource. Filesystemresource or Servletcontextresource.

You can enforce the specified resource type by specifying a prefix. The following two examples show if you force the use of Classpathresource and Urlresource.

<property name= "template" value= "Classpath:some/resource/path/mytemplate.txt" ><property name= "template" Value= "File:/some/resource/path/mytemplate.txt"/>


5.7Application Context andResourcePathConstruct the application context

A constructor that applies the context (for a specified application context) uses a string or array of strings to locate the resource, such as the path to the XML file that constructs the beandefinition.

When such a path does not have a prefix, the type of the resource is determined based on the type of the current application context. For example, if you create a classpathxmlapplicationcontext in the following way:

ApplicationContext CTX = new Classpathxmlapplicationcontext ("Conf/appcontext.xml");

The application context will be downloaded from classpath into the bean definition and treated as a classpathresource. But if you create a filesystemxmlapplicationcontext in the following way:

ApplicationContext CTX = new Filesystemxmlapplicationcontext ("Conf/appcontext.xml");


At this point the bean definition will be loaded from a location in the file system, relative to the path of the current working directory.

Note that if you have a special classpath prefix or a standard URL prefix on the path string, this overrides the default resource type. So the following filesystemxmlapplicationcontext will actually load the bean definition from classpath. But it is still a filesystemxmlapplicationcontext. If it is later used as a resourceloader, then any path without a prefix is still considered a path to the filesystem (note: Here I need to test if classpathxmlapplicationcontext and so on are in effect with the file prefix).

ApplicationContext CTX = new Filesystemxmlapplicationcontext ("Classpath:conf/appcontext.xml");

Create a Classpathxmlapplicationcontext instance--shortcut

Classpathxmlapplicationcontext exposes a number of constructors to provide convenience for instantiation. Most basic is a string array parameter that provides the file name of the XML file (no path), and the other parameter provides a class object. Then Classpathxmlapplicationcontext will get the path from the class object provided.

I hope the following example can make you see more clearly. Consider the following directory structure:

Com/foo/services.xmldaos.xmlmessengerservice.class

An Classpathxmlapplicationcontext instance can be instantiated as such:

ApplicationContext CTX = new Classpathxmlapplicationcontext (new string[] {"Services.xml", "Daos.xml"}, Messengerservice.class);

Some of the bean definitions are included in Services.xml and Daos.xml.


To apply a wildcard character in a resource path in the context Builder

The resource path parameter in the application context construction method may be a simple path (as shown above), which corresponds to a target resource of one by one, or contains a special "classpath*:" prefix and/ or an internal Ant-style regular expression (using Spring's pathmatcher tool to match). Both are valid wildcard characters.

One use of this mechanism is when using multi-module style application assembly. All modules can publish their own context definition fragments to a specified path. When the final application context is created using a path with the prefix "classpath:*", all component fragments will be automatically grouped together.

Note that this wildcard is intended to be used for the constructor of the application context (or when the Pathmatcher tool class is used directly) and is parsed during the construction period. It has no relation to the resource type. You cannot use the classpath*: prefix to create an actual resource, because at the same time resource and the underlying resource one by one correspond.


Ant-Style expressions

When the path includes an ant-style expression, such as:

/web-inf/*-context.xmlcom/mycompany/**/applicationcontext.xmlfile:c:/some/path/*-context.xmlclasspath:com/ Mycompany/**/applicationcontext.xml

The parser resolves the wildcard character based on a more complex but unambiguous procedure. It will start from the beginning to the last non-wildcard part to get a URL. If this URL is not a "jar:" URL or a container-related variable (such as "Zip:" in WebLogic, "Wsjar" in WebSphere), then it will be able to get a java.io.File and use this file to traverse the filesystem. In the case of the jar URL, the parser gets a java.net.JarURLConnection or manually parses the jar URL and then iterates through the contents of the jar file to parse the wildcard character.

Effects on Portability

If the specified path is a file URL (either explicitly or implicitly, because the underlying resourceloader is a file system Resourceloader), the wildcard character can work across platforms in this case.

If the specified path is a classpath location, the parser must get the URL of the path's non-wildcard part by calling Classloader.getresource (). Since this is only part of the path (not a file), in this case there is no explicit definition of what URL will be returned. In practice, always returns a Java.io.File object representing the directory ...

If a jar URL is obtained from the last non-wildcard part, the parser must be able to get a java.net.JarURLConnection from it or parse the jar URL manually to parse the wildcard character. This is true in most environments, but may not work in some cases. With regard to the wildcard character of the jar, it is strongly recommended that you thoroughly test the specific environment you are going to use.


classpath*: Prefix

When constructing an XML-based application context, a path string might use a special "classpath*:" prefix:

ApplicationContext CTX = new Classpathxmlapplicationcontext ("Classpath*:conf/appcontext.xml");

This special prefix indicates that all resources that match the name of the file under Classpath will be fetched (this is essentially through a classloader.getresources (...). called), and then assemble the acquired resources into the final application context definition.


classpath*: Portability

"classpath*:" Relies on the Getresources () method of the underlying ClassLoader. Since most application servers now provide their own classloader implementations, they may behave differently, especially when working with jar files. A simple test can determine whether classpath* is valid: Use ClassLoader to load a file in the jar under Classpath--getclass (). getClassLoader (). Getresources ("< Somefileinsidethejar> "). Then put two files of the same name in different locations for testing as above. If different results are returned, you will need to review the application server's documentation to find the settings that might affect the classloader behavior.

In the remainder of the location path, the classpath:* prefix can also be combined with a pathmatcher, such as "Classpath*:meta-inf/*-beans.xml". In this case, the strategy is fairly straightforward: first get the top-most-paid no-wildcard location path segment, then call Classloader.getresources (segment) to get all the matching resources, and then Pathmacher Policy is applied to every resource that is acquired.


Other notes about wildcard characters

Note that when "classpath*:" is used with an ant-style expression, you need to have at least one root directory before the expression starts, unless the destination file is on the file system. This means that an expression such as "classpath*:*. xml" will not be retrieved from a jar file in the root directory, but only from the extended directory of the root directory. This goes back to the limitations of the Classloader.getresources () method in the JDK, which returns the file system location (that is, the potential search root path) when an empty string is passed in.

If the root package being searched exists on more than one classpath, then the Ant-style expression is used with the "classpath:" prefix, and there is no guarantee that a matching underlying resource can be found. This is because of an underlying resource:

Com/mycompany/package1/service-context.xml

May exist only in one place, but when a path resembles the following:

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

When parsed, the parser only iterates over the URLs (the first) that are returned by GetResource ("Com/mycompany"). If the base package node "Com.mycompany" exists in more than one classloader location, then the actual resource may be later, or not the first, then the parser will not necessarily be able to find the resource. Therefore, a better way to do this is to use "classpath*:" To work with the same ant-style expressions, which will search for all classpath paths that contain the underlying package nodes.


Filesystemresource Precautions

A filesystemresource that is not loaded by filesystemapplicationcontext (that is, Filesystemapplicationcontext is not the real resourceloader) treats absolute paths and relative paths as normal conditions. The relative path is relative to the current working directory, and the absolute path is relative to the root of the file system.

However, for a forward compatible (historical) reason, when Filesystemapplicationcontext is Resourceloader, it is not the same. Filesystemapplicationcontext

Forces all of the Filesystemresource instances it loads to treat all paths as relative paths, regardless of whether they start with a backslash. This means that the following two pieces of code are equivalent:

ApplicationContext CTX = new Filesystemxmlapplicationcontext ("Conf/context.xml");
ApplicationContext CTX = new Filesystemxmlapplicationcontext ("/conf/context.xml");

The following are also the same (even if they are not the same is said, because one is the absolute one is relative):

Filesystemxmlapplicationcontext CTX = ...; Ctx.getresource ("Some/resource/path/mytemplate.txt");

Filesystemxmlapplicationcontext CTX = ...; Ctx.getresource ("/some/resource/path/mytemplate.txt");

In practical use, if you need to use absolute paths, it is best not to use Filesystemresource or filesystemxmlapplicationcontext, but to use Urlresource directly and specify the file: prefix

Actual context type doesn ' t matter, the Resourcewill always be Urlresourcectx.getresource ("file:/some/resource/path/ MyTemplate.txt ");

Force this filesystemxmlapplicationcontext to load its definition via a urlresourceapplicationcontext CTX = new Filesys Temxmlapplicationcontext ("File:/conf/context.xml");




Spring Official document translation--5. resources

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.