This article has participated in the Denver Nuggets Creators Camp 3 “More Productive writing” track, see details: Digg project | creators Camp 3 ongoing, “write” personal impact.
Spring defines the Resource interface for accessing resources. Generally, resources come in the form of urls loaded from external links and files retrieved from the system itself.
Spring’s Resource provides the following interface:
public interface Resource extends InputStreamSource {
boolean exists(a);
boolean isOpen(a);
URL getURL(a) throws IOException;
File getFile(a) throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename(a);
String getDescription(a);
}
Copy the code
Resource inherits the InputStreamSource interface, as defined below:
public interface InputStreamSource {
InputStream getInputStream(a) throws IOException;
}
Copy the code
Built-in Resource implementation
Spring has several built-in resource implementations:
- UrlResource
- ClassPathResource
- FileSystemResource
- ServletContextResource
- InputStreamResource
- ByteArrayResource
UrlResource
UrlResource encapsulates java.net.URL and can be used to access any object that is normally accessible through a URL, such as files, HTTP targets, FTP targets, and other objects. All urls can use a standardized prefix to represent a URL type. For example, file: indicates the path for accessing the file system. HTTP: Used to access resources over HTTP. FTP: Used to access resources through FTP.
ClassPathResource
Indicates that resources are loaded from the classpath. If the resource path is prefixed with ClassPath:, it is implicitly resolved as ClassPathResource.
Note that the resource implementation is resolved to java.io.File if the resource class File is in a File system, or java.net.URL if it is in a Jar package.
FileSystemResource
It is a Resource implementation of java.io.File and java.nio.file.Path, which can be resolved to File or URL.
ServletContextResource
This is the Resource implementation of the ServletContext that explains the relative paths in the root directory of the relevant Web application.
InputStreamResource
InputStreamResource is a Resource implementation of InputStream. Consider using it only if other Resource implementations are not available.
In contrast to other Resource implementations, it is a already-opened Resource descriptor, so isOpen() returns true. Don’t use the resource descriptor if you want to save it or read a stream multiple times.
ByteArrayResource
Is a Resource implementation of the ByteArray that creates a ByteArrayInputStream.
It’s useful for loading content from any given byte array without having to resort to the single-use InputStreamResource.
ResourceLoader
ResourceLoader is used to return Resource instances. Here is its definition:
public interface ResourceLoader {
Resource getResource(String location);
}
Copy the code
All Application Contexts implement the ResourceLoader class. Therefore, all Application Contexts can be used to fetch Resources.
When getResource () is called on a particular application context and the specified location path does not have a specific prefix, the resource type appropriate for that particular application context is returned. For example, suppose the ClassPathXmlApplicationContext instances execute the following code snippet:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
Copy the code
In the ClassPathXmlApplicationContext, this method returns ClassPathResource, if, in the FileSystemXmlApplicationContext method returns FileSystemResource. In WebApplicationContext, the method returns ServletContextResource. It returns the Resource implementation corresponding to the ApplicationContext.
Of course, you can force the ClassPathResource to be used regardless of what the ApplicationContext is. To do this you need to add the classpath: prefix. As follows:
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Copy the code
Also, you can enforce the use of UrlResource by adding the standard java.net.URL prefix.
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
Copy the code
ResourceLoaderAware
The ResourceLoaderAware interface is a special callback indicating that the component needs to provide a reference to ResourceLoader. Here is the definition of ResourceLoaderAware:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
Copy the code
When a class implements ResourceLoaderAware and is deployed to the Application Context, the entire class is identified as ResourceLoaderAware. Application Context is going to call the setResourceLoader method, Pass in itself as an argument (all Spring Application Contexts implement the ResourceLoader interface).
Instead of using the ResourceLoaderAware interface, you can also use automatic loading of ResourceLoader in your application components. You can use the traditional constructor or byType auto-loading mode. Or use annotations.
Resources as dependencies
If you want to inject static resources into beans, you can simply convert String paths into Resource objects. If the Bean defines a template property of type Resource, here is a very simple Resource configuration example:
@Data
public class BeanA {
private Resource template;
}
Copy the code
<bean id="myBean" class="com.flydean.beans.BeanA">
<property name="template" value="bean.properties"/>
</bean>
Copy the code
Tectonic ClassPathXmlApplicationContext – shortcut
ClassPathXmlApplicationContext provides a quick way to find out the resource path needs to be loaded.
You simply provide an array of strings that contain only the filename of the XML file itself (without leading path information) and a class. Then, ClassPathXmlApplicationContext derived from class provides path information.
As follows:
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"beanA.xml"}, BeanA.class);
}
Copy the code
Here is the file structure:
com/
flydean/
beans/
beanA.xml
BeanA.class
Copy the code
Resource path wildcard
Ant-style Patterns
Resource paths can be defined using ant-style wildcards. Here is an example of a path in an Ant-style pattern:
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
Copy the code
The classpath: prefix *
Construct an XML-based application context with the path address prefix classpath*: as follows:
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
Copy the code
What’s the difference between classpath* and classpath?
The classpath* will look for all matching classpath, and the classpath will only find the first matching resource.
FileSystemResource Precautions
Not connected to the FileSystemApplicationContext FileSystemResource (i.e., when FileSystemApplicationContext than actual ResourceLoader) can deal with the absolute and relative paths as expected. The relative path is relative to the current working directory, and the absolute path is relative to the root directory of the file system.
However, because of backward compatibility (history), when FileSystemApplicationContext is ResourceLoader, this change will happen. FileSystemApplicationContext forced all additional FileSystemResource instances will all location path as a relative path, regardless of whether they begin with leading forward slash. In practice, this means that the following example is equivalent:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
Copy the code
In practice, if you need the real absolute file system path, should avoid to use absolute paths with FileSystemResource or FileSystemXmlApplicationContext, and through the use of the file: URL prefix mandatory use UrlResource. The following example illustrates how to do this:
// 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");
Copy the code
See resources for examples in this section
See flydean’s blog for more tutorials