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