文档章节

Spring resource

zswitos
 zswitos
发布于 2015/04/25 14:40
字数 5348
阅读 75
收藏 0

Spring Resource 1


1、介绍

    java的标准的URL类不足够能访问大部分情况的资源,如没有一个标准的功能获取一个classpath或者想对于servletContext路径下的资源

2、spring resoruce class

    spring的resource是一个能够访问low-level resources的抽象接口

public interface InputStreamSource {   /**    * Return an {@link InputStream}.    * <p>It is expected that each call creates a <i>fresh</i> stream.    * <p>This requirement is particularly important when you consider an API such    * as JavaMail, which needs to be able to read the stream multiple times when    * creating mail attachments. For such a use case, it is <i>required</i>    * that each {@code getInputStream()} call returns a fresh stream.    * @return the input stream for the underlying resource (must not be {@code null})    * @throws IOException if the stream could not be opened    * @see org.springframework.mail.javamail.MimeMessageHelper#addAttachment(String, InputStreamSource)    */   InputStream getInputStream() throws IOException;}
/* * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.core.io;import java.io.File;import java.io.IOException;import java.net.URI;import java.net.URL;/** * Interface for a resource descriptor that abstracts from the actual * type of underlying resource, such as a file or class path resource. * * <p>An InputStream can be opened for every resource if it exists in * physical form, but a URL or File handle can just be returned for * certain resources. The actual behavior is implementation-specific. * * @author Juergen Hoeller * @since 28.12.2003 * @see #getInputStream() * @see #getURL() * @see #getURI() * @see #getFile() * @see WritableResource * @see ContextResource * @see FileSystemResource * @see ClassPathResource * @see UrlResource * @see ByteArrayResource * @see InputStreamResource * @see PathResource */public interface Resource extends InputStreamSource {   /**    * Return whether this resource actually exists in physical form.    * <p>This method performs a definitive existence check, whereas the    * existence of a {@code Resource} handle only guarantees a    * valid descriptor handle.    */   boolean exists();   /**    * Return whether the contents of this resource can be read,    * e.g. via {@link #getInputStream()} or {@link #getFile()}.    * <p>Will be {@code true} for typical resource descriptors;    * note that actual content reading may still fail when attempted.    * However, a value of {@code false} is a definitive indication    * that the resource content cannot be read.    * @see #getInputStream()    */   boolean isReadable();   /**    * Return whether this resource represents a handle with an open    * stream. If true, the InputStream cannot be read multiple times,    * and must be read and closed to avoid resource leaks.    * <p>Will be {@code false} for typical resource descriptors.    */   boolean isOpen();   /**    * Return a URL handle for this resource.    * @throws IOException if the resource cannot be resolved as URL,    * i.e. if the resource is not available as descriptor    */   URL getURL() throws IOException;   /**    * Return a URI handle for this resource.    * @throws IOException if the resource cannot be resolved as URI,    * i.e. if the resource is not available as descriptor    */   URI getURI() throws IOException;   /**    * Return a File handle for this resource.    * @throws IOException if the resource cannot be resolved as absolute    * file path, i.e. if the resource is not available in a file system    */   File getFile() throws IOException;   /**    * Determine the content length for this resource.    * @throws IOException if the resource cannot be resolved    * (in the file system or as some other known physical resource type)    */   long contentLength() throws IOException;   /**    * Determine the last-modified timestamp for this resource.    * @throws IOException if the resource cannot be resolved    * (in the file system or as some other known physical resource type)    */   long lastModified() throws IOException;   /**    * Create a resource relative to this resource.    * @param relativePath the relative path (relative to this resource)    * @return the resource handle for the relative resource    * @throws IOException if the relative resource cannot be determined    */   Resource createRelative(String relativePath) throws IOException;   /**    * Determine a filename for this resource, i.e. typically the last    * part of the path: for example, "myfile.txt".    * <p>Returns {@code null} if this type of resource does not    * have a filename.    */   String getFilename();   /**    * Return a description for this resource,    * to be used for error output when working with the resource.    * <p>Implementations are also encouraged to return this value    * from their {@code toString} method.    * @see Object#toString()    */   String getDescription();}


它有好多的实现类

UrlResource

/* * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.core.io;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URI;import java.net.URISyntaxException;import java.net.URL;import java.net.URLConnection;import org.springframework.util.Assert;import org.springframework.util.ResourceUtils;import org.springframework.util.StringUtils;/** * {@link Resource} implementation for {@code java.net.URL} locators. * Obviously supports resolution as URL, and also as File in case of * the "file:" protocol. * * @author Juergen Hoeller * @since 28.12.2003 * @see java.net.URL */public class UrlResource extends AbstractFileResolvingResource {   /**    * Original URI, if available; used for URI and File access.    */   private final URI uri;   /**    * Original URL, used for actual access.    */   private final URL url;   /**    * Cleaned URL (with normalized path), used for comparisons.    */   private final URL cleanedUrl;   /**    * Create a new UrlResource based on the given URI object.    * @param uri a URI    * @throws MalformedURLException if the given URL path is not valid    */   public UrlResource(URI uri) throws MalformedURLException {      Assert.notNull(uri, "URI must not be null");      this.uri = uri;      this.url = uri.toURL();      this.cleanedUrl = getCleanedUrl(this.url, uri.toString());   }   /**    * Create a new UrlResource based on the given URL object.    * @param url a URL    */   public UrlResource(URL url) {      Assert.notNull(url, "URL must not be null");      this.url = url;      this.cleanedUrl = getCleanedUrl(this.url, url.toString());      this.uri = null;   }   /**    * Create a new UrlResource based on a URL path.    * <p>Note: The given path needs to be pre-encoded if necessary.    * @param path a URL path    * @throws MalformedURLException if the given URL path is not valid    * @see java.net.URL#URL(String)    */   public UrlResource(String path) throws MalformedURLException {      Assert.notNull(path, "Path must not be null");      this.uri = null;      this.url = new URL(path);      this.cleanedUrl = getCleanedUrl(this.url, path);   }   /**    * Create a new UrlResource based on a URI specification.    * <p>The given parts will automatically get encoded if necessary.    * @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon);    * also known as "scheme"    * @param location the location (e.g. the file path within that protocol);    * also known as "scheme-specific part"    * @throws MalformedURLException if the given URL specification is not valid    * @see java.net.URI#URI(String, String, String)    */   public UrlResource(String protocol, String location) throws MalformedURLException  {      this(protocol, location, null);   }   /**    * Create a new UrlResource based on a URI specification.    * <p>The given parts will automatically get encoded if necessary.    * @param protocol the URL protocol to use (e.g. "jar" or "file" - without colon);    * also known as "scheme"    * @param location the location (e.g. the file path within that protocol);    * also known as "scheme-specific part"    * @param fragment the fragment within that location (e.g. anchor on an HTML page,    * as following after a "#" separator)    * @throws MalformedURLException if the given URL specification is not valid    * @see java.net.URI#URI(String, String, String)    */   public UrlResource(String protocol, String location, String fragment) throws MalformedURLException  {      try {         this.uri = new URI(protocol, location, fragment);         this.url = this.uri.toURL();         this.cleanedUrl = getCleanedUrl(this.url, this.uri.toString());      }      catch (URISyntaxException ex) {         MalformedURLException exToThrow = new MalformedURLException(ex.getMessage());         exToThrow.initCause(ex);         throw exToThrow;      }   }   /**    * Determine a cleaned URL for the given original URL.    * @param originalUrl the original URL    * @param originalPath the original URL path    * @return the cleaned URL    * @see org.springframework.util.StringUtils#cleanPath    */   private URL getCleanedUrl(URL originalUrl, String originalPath) {      try {         return new URL(StringUtils.cleanPath(originalPath));      }      catch (MalformedURLException ex) {         // Cleaned URL path cannot be converted to URL         // -> take original URL.         return originalUrl;      }   }   /**    * This implementation opens an InputStream for the given URL.    * It sets the "UseCaches" flag to {@code false},    * mainly to avoid jar file locking on Windows.    * @see java.net.URL#openConnection()    * @see java.net.URLConnection#setUseCaches(boolean)    * @see java.net.URLConnection#getInputStream()    */   @Override   public InputStream getInputStream() throws IOException {      URLConnection con = this.url.openConnection();      ResourceUtils.useCachesIfNecessary(con);      try {         return con.getInputStream();      }      catch (IOException ex) {         // Close the HTTP connection (if applicable).         if (con instanceof HttpURLConnection) {            ((HttpURLConnection) con).disconnect();         }         throw ex;      }   }   /**    * This implementation returns the underlying URL reference.    */   @Override   public URL getURL() throws IOException {      return this.url;   }   /**    * This implementation returns the underlying URI directly,    * if possible.    */   @Override   public URI getURI() throws IOException {      if (this.uri != null) {         return this.uri;      }      else {         return super.getURI();      }   }   /**    * This implementation returns a File reference for the underlying URL/URI,    * provided that it refers to a file in the file system.    * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String)    */   @Override   public File getFile() throws IOException {      if (this.uri != null) {         return super.getFile(this.uri);      }      else {         return super.getFile();      }   }   /**    * This implementation creates a UrlResource, applying the given path    * relative to the path of the underlying URL of this resource descriptor.    * @see java.net.URL#URL(java.net.URL, String)    */   @Override   public Resource createRelative(String relativePath) throws MalformedURLException {      if (relativePath.startsWith("/")) {         relativePath = relativePath.substring(1);      }      return new UrlResource(new URL(this.url, relativePath));   }   /**    * This implementation returns the name of the file that this URL refers to.    * @see java.net.URL#getFile()    * @see java.io.File#getName()    */   @Override   public String getFilename() {      return new File(this.url.getFile()).getName();   }   /**    * This implementation returns a description that includes the URL.    */   @Override   public String getDescription() {      return "URL [" + this.url + "]";   }   /**    * This implementation compares the underlying URL references.    */   @Override   public boolean equals(Object obj) {      return (obj == this ||         (obj instanceof UrlResource && this.cleanedUrl.equals(((UrlResource) obj).cleanedUrl)));   }   /**    * This implementation returns the hash code of the underlying URL reference.    */   @Override   public int hashCode() {      return this.cleanedUrl.hashCode();   }}

ClassPathResource:

    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.

/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.core.io;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.net.URL;import org.springframework.util.Assert;import org.springframework.util.ClassUtils;import org.springframework.util.ObjectUtils;import org.springframework.util.StringUtils;/** * {@link Resource} implementation for class path resources. * Uses either a given ClassLoader or a given Class for loading resources. * * <p>Supports resolution as {@code java.io.File} if the class path * resource resides in the file system, but not for resources in a JAR. * Always supports resolution as URL. * * @author Juergen Hoeller * @author Sam Brannen * @since 28.12.2003 * @see ClassLoader#getResourceAsStream(String) * @see Class#getResourceAsStream(String) */public class ClassPathResource extends AbstractFileResolvingResource {   private final String path;   private ClassLoader classLoader;   private Class<?> clazz;   /**    * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.    * A leading slash will be removed, as the ClassLoader resource access    * methods will not accept it.    * <p>The thread context class loader will be used for    * loading the resource.    * @param path the absolute path within the class path    * @see java.lang.ClassLoader#getResourceAsStream(String)    * @see org.springframework.util.ClassUtils#getDefaultClassLoader()    */   public ClassPathResource(String path) {      this(path, (ClassLoader) null);   }   /**    * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.    * A leading slash will be removed, as the ClassLoader resource access    * methods will not accept it.    * @param path the absolute path within the classpath    * @param classLoader the class loader to load the resource with,    * or {@code null} for the thread context class loader    * @see ClassLoader#getResourceAsStream(String)    */   public ClassPathResource(String path, ClassLoader classLoader) {      Assert.notNull(path, "Path must not be null");      String pathToUse = StringUtils.cleanPath(path);      if (pathToUse.startsWith("/")) {         pathToUse = pathToUse.substring(1);      }      this.path = pathToUse;      this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());   }   /**    * Create a new {@code ClassPathResource} for {@code Class} usage.    * The path can be relative to the given class, or absolute within    * the classpath via a leading slash.    * @param path relative or absolute path within the class path    * @param clazz the class to load resources with    * @see java.lang.Class#getResourceAsStream    */   public ClassPathResource(String path, Class<?> clazz) {      Assert.notNull(path, "Path must not be null");      this.path = StringUtils.cleanPath(path);      this.clazz = clazz;   }   /**    * Create a new {@code ClassPathResource} with optional {@code ClassLoader}    * and {@code Class}. Only for internal usage.    * @param path relative or absolute path within the classpath    * @param classLoader the class loader to load the resource with, if any    * @param clazz the class to load resources with, if any    */   protected ClassPathResource(String path, ClassLoader classLoader, Class<?> clazz) {      this.path = StringUtils.cleanPath(path);      this.classLoader = classLoader;      this.clazz = clazz;   }   /**    * Return the path for this resource (as resource path within the class path).    */   public final String getPath() {      return this.path;   }   /**    * Return the ClassLoader that this resource will be obtained from.    */   public final ClassLoader getClassLoader() {      return (this.clazz != null ? this.clazz.getClassLoader() : this.classLoader);   }   /**    * This implementation checks for the resolution of a resource URL.    * @see java.lang.ClassLoader#getResource(String)    * @see java.lang.Class#getResource(String)    */   @Override   public boolean exists() {      return (resolveURL() != null);   }   /**    * Resolves a URL for the underlying class path resource.    * @return the resolved URL, or {@code null} if not resolvable    */   protected URL resolveURL() {      if (this.clazz != null) {         return this.clazz.getResource(this.path);      }      else if (this.classLoader != null) {         return this.classLoader.getResource(this.path);      }      else {         return ClassLoader.getSystemResource(this.path);      }   }   /**    * This implementation opens an InputStream for the given class path resource.    * @see java.lang.ClassLoader#getResourceAsStream(String)    * @see java.lang.Class#getResourceAsStream(String)    */   @Override   public InputStream getInputStream() throws IOException {      InputStream is;      if (this.clazz != null) {         is = this.clazz.getResourceAsStream(this.path);      }      else if (this.classLoader != null) {         is = this.classLoader.getResourceAsStream(this.path);      }      else {         is = ClassLoader.getSystemResourceAsStream(this.path);      }      if (is == null) {         throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");      }      return is;   }   /**    * This implementation returns a URL for the underlying class path resource,    * if available.    * @see java.lang.ClassLoader#getResource(String)    * @see java.lang.Class#getResource(String)    */   @Override   public URL getURL() throws IOException {      URL url = resolveURL();      if (url == null) {         throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");      }      return url;   }   /**    * This implementation creates a ClassPathResource, applying the given path    * relative to the path of the underlying resource of this descriptor.    * @see org.springframework.util.StringUtils#applyRelativePath(String, String)    */   @Override   public Resource createRelative(String relativePath) {      String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);      return new ClassPathResource(pathToUse, this.classLoader, this.clazz);   }   /**    * This implementation returns the name of the file that this class path    * resource refers to.    * @see org.springframework.util.StringUtils#getFilename(String)    */   @Override   public String getFilename() {      return StringUtils.getFilename(this.path);   }   /**    * This implementation returns a description that includes the class path location.    */   @Override   public String getDescription() {      StringBuilder builder = new StringBuilder("class path resource [");      String pathToUse = path;      if (this.clazz != null && !pathToUse.startsWith("/")) {         builder.append(ClassUtils.classPackageAsResourcePath(this.clazz));         builder.append('/');      }      if (pathToUse.startsWith("/")) {         pathToUse = pathToUse.substring(1);      }      builder.append(pathToUse);      builder.append(']');      return builder.toString();   }   /**    * This implementation compares the underlying class path locations.    */   @Override   public boolean equals(Object obj) {      if (obj == this) {         return true;      }      if (obj instanceof ClassPathResource) {         ClassPathResource otherRes = (ClassPathResource) obj;         return (this.path.equals(otherRes.path) &&               ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) &&               ObjectUtils.nullSafeEquals(this.clazz, otherRes.clazz));      }      return false;   }   /**    * This implementation returns the hash code of the underlying    * class path location.    */   @Override   public int hashCode() {      return this.path.hashCode();   }}


FileSystemResource :

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

/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.core.io;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URI;import java.net.URL;import org.springframework.util.Assert;import org.springframework.util.StringUtils;/** * {@link Resource} implementation for {@code java.io.File} handles. * Obviously supports resolution as File, and also as URL. * Implements the extended {@link WritableResource} interface. * * @author Juergen Hoeller * @since 28.12.2003 * @see java.io.File */public class FileSystemResource extends AbstractResource implements WritableResource {   private final File file;   private final String path;   /**    * Create a new {@code FileSystemResource} from a {@link File} handle.    * <p>Note: When building relative resources via {@link #createRelative},    * the relative path will apply <i>at the same directory level</i>:    * e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"!    * If you prefer to have relative paths built underneath the given root    * directory, use the {@link #FileSystemResource(String) constructor with a file path}    * to append a trailing slash to the root path: "C:/dir1/", which    * indicates this directory as root for all relative paths.    * @param file a File handle    */   public FileSystemResource(File file) {      Assert.notNull(file, "File must not be null");      this.file = file;      this.path = StringUtils.cleanPath(file.getPath());   }   /**    * Create a new {@code FileSystemResource} from a file path.    * <p>Note: When building relative resources via {@link #createRelative},    * it makes a difference whether the specified resource base path here    * ends with a slash or not. In the case of "C:/dir1/", relative paths    * will be built underneath that root: e.g. relative path "dir2" ->    * "C:/dir1/dir2". In the case of "C:/dir1", relative paths will apply    * at the same directory level: relative path "dir2" -> "C:/dir2".    * @param path a file path    */   public FileSystemResource(String path) {      Assert.notNull(path, "Path must not be null");      this.file = new File(path);      this.path = StringUtils.cleanPath(path);   }   /**    * Return the file path for this resource.    */   public final String getPath() {      return this.path;   }   /**    * This implementation returns whether the underlying file exists.    * @see java.io.File#exists()    */   @Override   public boolean exists() {      return this.file.exists();   }   /**    * This implementation checks whether the underlying file is marked as readable    * (and corresponds to an actual file with content, not to a directory).    * @see java.io.File#canRead()    * @see java.io.File#isDirectory()    */   @Override   public boolean isReadable() {      return (this.file.canRead() && !this.file.isDirectory());   }   /**    * This implementation opens a FileInputStream for the underlying file.    * @see java.io.FileInputStream    */   @Override   public InputStream getInputStream() throws IOException {      return new FileInputStream(this.file);   }   /**    * This implementation returns a URL for the underlying file.    * @see java.io.File#toURI()    */   @Override   public URL getURL() throws IOException {      return this.file.toURI().toURL();   }   /**    * This implementation returns a URI for the underlying file.    * @see java.io.File#toURI()    */   @Override   public URI getURI() throws IOException {      return this.file.toURI();   }   /**    * This implementation returns the underlying File reference.    */   @Override   public File getFile() {      return this.file;   }   /**    * This implementation returns the underlying File's length.    */   @Override   public long contentLength() throws IOException {      return this.file.length();   }   /**    * This implementation creates a FileSystemResource, applying the given path    * relative to the path of the underlying file of this resource descriptor.    * @see org.springframework.util.StringUtils#applyRelativePath(String, String)    */   @Override   public Resource createRelative(String relativePath) {      String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);      return new FileSystemResource(pathToUse);   }   /**    * This implementation returns the name of the file.    * @see java.io.File#getName()    */   @Override   public String getFilename() {      return this.file.getName();   }   /**    * This implementation returns a description that includes the absolute    * path of the file.    * @see java.io.File#getAbsolutePath()    */   @Override   public String getDescription() {      return "file [" + this.file.getAbsolutePath() + "]";   }   // implementation of WritableResource   /**    * This implementation checks whether the underlying file is marked as writable    * (and corresponds to an actual file with content, not to a directory).    * @see java.io.File#canWrite()    * @see java.io.File#isDirectory()    */   @Override   public boolean isWritable() {      return (this.file.canWrite() && !this.file.isDirectory());   }   /**    * This implementation opens a FileOutputStream for the underlying file.    * @see java.io.FileOutputStream    */   @Override   public OutputStream getOutputStream() throws IOException {      return new FileOutputStream(this.file);   }   /**    * This implementation compares the underlying File references.    */   @Override   public boolean equals(Object obj) {      return (obj == this ||         (obj instanceof FileSystemResource && this.path.equals(((FileSystemResource) obj).path)));   }   /**    * This implementation returns the hash code of the underlying File reference.    */   @Override   public int hashCode() {      return this.path.hashCode();   }}

ServletContextResource :

    This is a Resource implementation for ServletContext resources, interpreting relative paths within
the relevant web application’s root directory.
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.

ServletContextResourceServletContextResourceServletContextResource

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.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.

InputStreamResourceInputStreamResource


ByteArrayResource:

    This is a Resource implementation for a given byte array. It creates a ByteArrayInputStream for the given byte array. It’s useful for loading content from any given byte array, without having to resort to a single-use InputStreamResource.


ByteArrayResourceByteArrayResourceByteArrayResource


3、Spring ResourceLoader

这个接口是用来获取Resource类的


有第二部分可知每个Resource会对应有个ResourceLoader类

/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.core.io;import org.springframework.util.ResourceUtils;/** * Strategy interface for loading resources (e.. class path or file system * resources). An {@link org.springframework.context.ApplicationContext} * is required to provide this functionality, plus extended * {@link org.springframework.core.io.support.ResourcePatternResolver} support. * * <p>{@link DefaultResourceLoader} is a standalone implementation that is * usable outside an ApplicationContext, also used by {@link ResourceEditor}. * * <p>Bean properties of type Resource and Resource array can be populated * from Strings when running in an ApplicationContext, using the particular * context's resource loading strategy. * * @author Juergen Hoeller * @since 10.03.2004 * @see Resource * @see org.springframework.core.io.support.ResourcePatternResolver * @see org.springframework.context.ApplicationContext * @see org.springframework.context.ResourceLoaderAware */public interface ResourceLoader {   /** Pseudo URL prefix for loading from the class path: "classpath:" */   String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;   /**    * Return a Resource handle for the specified resource.    * The handle should always be a reusable resource descriptor,    * allowing for multiple {@link Resource#getInputStream()} calls.    * <p><ul>    * <li>Must support fully qualified URLs, e.g. "file:C:/test.dat".    * <li>Must support classpath pseudo-URLs, e.g. "classpath:test.dat".    * <li>Should support relative file paths, e.g. "WEB-INF/test.dat".    * (This will be implementation-specific, typically provided by an    * ApplicationContext implementation.)    * </ul>    * <p>Note that a Resource handle does not imply an existing resource;    * you need to invoke {@link Resource#exists} to check for existence.    * @param location the resource location    * @return a corresponding Resource handle    * @see #CLASSPATH_URL_PREFIX    * @see org.springframework.core.io.Resource#exists    * @see org.springframework.core.io.Resource#getInputStream    */   Resource getResource(String location);   /**    * Expose the ClassLoader used by this ResourceLoader.    * <p>Clients which need to access the ClassLoader directly can do so    * in a uniform manner with the ResourceLoader, rather than relying    * on the thread context ClassLoader.    * @return the ClassLoader (only {@code null} if even the system    * ClassLoader isn't accessible)    * @see org.springframework.util.ClassUtils#getDefaultClassLoader()    */   ClassLoader getClassLoader();}

    

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

当你这样获取一个资源的时候,ctx为ClassPathXmlApplicationContext得到ClassPathResource,FileSystemXmlApplicationContext得到FileSystemResource,WebApplicationContext,得到ServletContextResource,用啥环境的什么资源

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

可以这样子指定资源的url


Table 6.1. Resource strings

Prefix
Example Explanation
classpath: classpath:com/myapp/config.xml Loaded from the classpath.
file: file:///data/config.xml Loaded as a URL, from thefilesystem.
http: http://myserver/logo.png Loaded as a URL.
(none) /data/config.xml Depends on the underlying ApplicationContext.

 

4、The ResourceLoaderAware interface

/* * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.context;import org.springframework.beans.factory.Aware;import org.springframework.core.io.ResourceLoader;/** * Interface to be implemented by any object that wishes to be notified of * the <b>ResourceLoader</b> (typically the ApplicationContext) that it runs in. * This is an alternative to a full ApplicationContext dependency via the * ApplicationContextAware interface. * * <p>Note that Resource dependencies can also be exposed as bean properties * of type Resource, populated via Strings with automatic type conversion by * the bean factory. This removes the need for implementing any callback * interface just for the purpose of accessing a specific file resource. * * <p>You typically need a ResourceLoader when your application object has * to access a variety of file resources whose names are calculated. A good * strategy is to make the object use a DefaultResourceLoader but still * implement ResourceLoaderAware to allow for overriding when running in an * ApplicationContext. See ReloadableResourceBundleMessageSource for an example. * * <p>A passed-in ResourceLoader can also be checked for the * <b>ResourcePatternResolver</b> interface and cast accordingly, to be able * to resolve resource patterns into arrays of Resource objects. This will always * work when running in an ApplicationContext (the context interface extends * ResourcePatternResolver). Use a PathMatchingResourcePatternResolver as default. * See also the {@code ResourcePatternUtils.getResourcePatternResolver} method. * * <p>As alternative to a ResourcePatternResolver dependency, consider exposing * bean properties of type Resource array, populated via pattern Strings with * automatic type conversion by the bean factory. * * @author Juergen Hoeller * @author Chris Beams * @since 10.03.2004 * @see ApplicationContextAware * @see org.springframework.beans.factory.InitializingBean * @see org.springframework.core.io.Resource * @see org.springframework.core.io.support.ResourcePatternResolver * @see org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver * @see org.springframework.core.io.DefaultResourceLoader * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver * @see org.springframework.context.support.ReloadableResourceBundleMessageSource */public interface ResourceLoaderAware extends Aware {   /**    * Set the ResourceLoader that this object runs in.    * <p>This might be a ResourcePatternResolver, which can be checked    * through {@code instanceof ResourcePatternResolver}. See also the    * {@code ResourcePatternUtils.getResourcePatternResolver} method.    * <p>Invoked after population of normal bean properties but before an init callback    * like InitializingBean's {@code afterPropertiesSet} or a custom init-method.    * Invoked before ApplicationContextAware's {@code setApplicationContext}.    * @param resourceLoader ResourceLoader object to be used by this object    * @see org.springframework.core.io.support.ResourcePatternResolver    * @see org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver    */   void setResourceLoader(ResourceLoader resourceLoader);}

获取ResourceLoader的方法实现 ResourceLoaderAware 这个接口,在容器启动给你注入(这个样子不好,耦合api)

第二种做法用注解

@Autowired private ResourceLoader resourceLoader;

看来spring为大家提供了好多Aware接口去获取系统的对象啊这个一个扩展思路,可以借鉴下!


4、何时加载Resource


ApplicationContext applicationContext =
        new FileSystemXmlApplicationContext("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml");

为例子,在

 1

FileSystemXmlApplicationContext("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml");
调用
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
   this(new String[] {configLocation}, true, null);
}
再调用
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {

   super(parent);
   setConfigLocations(configLocations);
   if (refresh) {
      refresh();
   }
}


一直调用至父类 AbstractApplicationContext
public AbstractApplicationContext(ApplicationContext parent) {
   this();
   setParent(parent);
}

在调用
public AbstractApplicationContext() {
   this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
   return new PathMatchingResourcePatternResolver(this);
}
这个时候获取Resource的Resolver类被设定了
PathMatchingResourcePatternResolver

public PathMatchingResourcePatternResolver() {
        this.resourceLoader = new DefaultResourceLoader();
    }

public ResourceLoader getResourceLoader() {
   return this.resourceLoader;
}

@Override
public ClassLoader getClassLoader() {
   return getResourceLoader().getClassLoader();
}

@Override
public Resource[] getResources(String locationPattern) throws IOException {
   Assert.notNull(locationPattern, "Location pattern must not be null");
   if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
      // a class path resource (multiple resources for same name possible)
      if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
         // a class path resource pattern
         return findPathMatchingResources(locationPattern);
      }
      else {
         // all class path resources with the given name
         return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
      }
   }
   else {
      // Only look for a pattern after a prefix here
      // (to not get fooled by a pattern symbol in a strange prefix).
      int prefixEnd = locationPattern.indexOf(":") + 1;
      if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
         // a file pattern
         return findPathMatchingResources(locationPattern);
      }
      else {
         // a single resource with the given name
         return new Resource[] {getResourceLoader().getResource(locationPattern)};
      }
   }
}


再获取资源的时候会调用DefaultResourceLoader的getResource

@Override
public Resource getResource(String location) {
   Assert.notNull(location, "Location must not be null");
   if (location.startsWith("/")) {
      return getResourceByPath(location);
   }
   else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
      return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
   }
   else {
      try {
         // Try to parse the location as a URL...
         URL url = new URL(location);
         return new UrlResource(url);
      }
      catch (MalformedURLException ex) {
         // No URL -> resolve as resource path.
         return getResourceByPath(location);
      }
   }
}

ok至此获取资源的流程清晰了

别忘记此时指示初始化了,还没有被调用,回到

public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
     // Prepare this context for refreshing.
     prepareRefresh();

     // Tell the subclass to refresh the internal bean factory.
     ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

     // Prepare the bean factory for use in this context.
     prepareBeanFactory(beanFactory);

     try {
        // Allows post-processing of the bean factory in context subclasses.
        postProcessBeanFactory(beanFactory);

        // Invoke factory processors registered as beans in the context.
        invokeBeanFactoryPostProcessors(beanFactory);

        // Register bean processors that intercept bean creation.
        registerBeanPostProcessors(beanFactory);

        // Initialize message source for this context.
        initMessageSource();

        // Initialize event multicaster for this context.
        initApplicationEventMulticaster();

        // Initialize other special beans in specific context subclasses.
        onRefresh();

        // Check for listener beans and register them.
        registerListeners();

        // Instantiate all remaining (non-lazy-init) singletons.
        finishBeanFactoryInitialization(beanFactory);

        // Last step: publish corresponding event.
        finishRefresh();
     }

     catch (BeansException ex) {
        logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);

        // Destroy already created singletons to avoid dangling resources.
        destroyBeans();

        // Reset 'active' flag.
        cancelRefresh(ex);

        // Propagate exception to caller.
        throw ex;
     }
  }
}
 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
   }
   return beanFactory;
}


protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

到了关键了在

loadBeanDefinitions(beanFactory);方法时候

AbstractXmlApplicationContext的

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
   if (configResources != null) {
      reader.loadBeanDefinitions(configResources);
   }
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      reader.loadBeanDefinitions(configLocations);
   }
}

然后是

AbstractBeanDefinitionReader的
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
   Assert.notNull(locations, "Location array must not be null");
   int counter = 0;
   for (String location : locations) {
      counter += loadBeanDefinitions(location);
   }
   return counter;
}

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
   ResourceLoader resourceLoader = getResourceLoader();
   if (resourceLoader == null) {
      throw new BeanDefinitionStoreException(
            "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
   }

   if (resourceLoader instanceof ResourcePatternResolver) {
      // Resource pattern matching available.
      try {
         Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
         int loadCount = loadBeanDefinitions(resources);
         if (actualResources != null) {
            for (Resource resource : resources) {
               actualResources.add(resource);
            }
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
         }
         return loadCount;
      }
      catch (IOException ex) {
         throw new BeanDefinitionStoreException(
               "Could not resolve bean definition resource pattern [" + location + "]", ex);
      }
   }
   else {
      // Can only load single resources by absolute URL.
      Resource resource = resourceLoader.getResource(location);
      int loadCount = loadBeanDefinitions(resource);
      if (actualResources != null) {
         actualResources.add(resource);
      }
      if (logger.isDebugEnabled()) {
         logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
      }
      return loadCount;
   }
}





@Override
public Resource[] getResources(String locationPattern) throws IOException {
   return this.resourcePatternResolver.getResources(locationPattern);
}

即是调用PathMatchingResourcePatternResolver的getResources

@Override
public Resource[] getResources(String locationPattern) throws IOException {
   Assert.notNull(locationPattern, "Location pattern must not be null");
   if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
      // a class path resource (multiple resources for same name possible)
      if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
         // a class path resource pattern
         return findPathMatchingResources(locationPattern);
      }
      else {
         // all class path resources with the given name
         return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
      }
   }
   else {
      // Only look for a pattern after a prefix here
      // (to not get fooled by a pattern symbol in a strange prefix).
      int prefixEnd = locationPattern.indexOf(":") + 1;
      if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
         // a file pattern
         return findPathMatchingResources(locationPattern);
      }
      else {
         // a single resource with the given name
         return new Resource[] {getResourceLoader().getResource(locationPattern)};
      }
   }
}

ok完成了 入口就是在

AbstractApplicationContext的refresh方法里面的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


© 著作权归作者所有

共有 人打赏支持
zswitos
粉丝 4
博文 58
码字总数 54950
作品 0
海淀
程序员
Spring中formdata方式提交json对象和file之一

问题 想使用vue-resource表单提交方式到spring,这个表单中包含json对象和file对象。 思路 将json对象和file对象都放到表单提交方式里面的中,并在中指定内容格式。 步骤 Spring实现和配置 ...

亚林瓜子
06/12
0
0
使用import简化spring的配置文件 (转载)

Spring中用import导入配置文件 原文地址:使用import简化spring的配置文件 (转载)作者:瓦砾 对于spring配置文件的编写,我想,对于经历过庞大项目的人,都有那种恐惧的心理,太多的配置文件...

blooms
2012/09/13
0
0
关于spring 注解,初始化的问题

前段时间用quartz,集成于spring,有些问题,特记下来,spring的初始化,这个想必在独立程序中是没有多大的问题的,因为应用spring和quartz的集成完成动态任务的更新,@Service , @Resourc...

石头哥哥
2013/03/10
0
0
Spring 常用的注解及“依赖注入”的实现

1、spring注解 @Controller 声明Action组件 @Service 声明Service组件 @Service("myMovieLister") @Repository 声明Dao组件 @Component 泛指组件, 当不好归类时. @RequestMapping("/menu") ......

沉淀人生
05/28
0
0
Spring组件注解和注入注解内部方式的区别

一、@Component、@Repository、@Service、@Controller区别 Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。...

思悟修
2015/08/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

jquery创建类似于java的map

var map = {}; // Map map = new HashMap(); map[key] = value; // map.put(key, value); var value = map[key]; // Object value = map.get(key); var has = key in map; // boolean has = ......

SuperDabai
32分钟前
0
0
java大数据转换16进制转10进制

public static void main(String[] args) {String hex = "0xdbf3accc683297cf0000";BigInteger amount = new BigInteger(hex.substring(2), 16);System.out.println(amount);......

任梁荣
昨天
1
0
OSChina 周六乱弹 —— 目测我们程序员丁克的几率不大

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @真Skr小机灵鬼儿:8.13分享Jocelyn Pook/Russian Red的单曲《Loving Strangers》 《Loving Strangers》- Jocelyn Pook/Russian Red 手机党少...

小小编辑
昨天
9
3
TypeScript基础入门 - 函数 - 剩余参数

转载 TypeScript基础入门 - 函数 - 剩余参数 项目实践仓库 https://github.com/durban89/typescript_demo.gittag: 1.2.1 为了保证后面的学习演示需要安装下ts-node,这样后面的每个操作都能...

durban
昨天
1
0
OpenCV边缘检测算子原理总结及实现

1. 拉普拉斯算子 原理:是一种基于图像导数运算的高通线性滤波器。它通过二阶导数来度量图像函数的曲率。 拉普拉斯算子是最简单的各向同性微分算子,它具有旋转不变性。一个二维图像函数的拉...

漫步当下
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部