Spring之Resource

Spring之所以抽象Resource接口,是因为传统的java使用URL和标准的handler来处置资源。但是有个局限是不能直接读取classpath下的资源。因此Spring定义了一套接口。这套接口分为两部分,Resource和ResourceLoader,其中是对资源的抽象,后者负责加载资源。Spring的ApplicationContext实现了ResourceLoader接口。

Resource

首先看Resource的接口定义。

public interface Resource extends InputStreamSource {

   boolean exists();

   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;

   File getFile() throws IOException;

   long contentLength() throws IOException;

    */
   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;

   String getFilename();

   String getDescription();

}
public interface InputStreamSource {

InputStream getInputStream() throws IOException;
}

以下接口简单明了,唯一需要注意的就是方法isOpen(),返回true表示此资源可以被多次读取,且需要使用者关闭。典型实现返回的都是false.

Resource的接口有子接口和几个实现类,其基本结构继承如下:

首先是包含两个子接口WritableResource 扩展了资源的可写性,ContextResource扩展,在某个上下文中读取资源。

所有的具体实现类都继承AbstractResource。从名称上可以明显的看出,不同的实现类负责不同形式的资源。

其中FileSystemResource extendsAbstractResource implements WritableResource ,这是一种很常见的扩展方式。

ResourceLoader

Spring提供了很多个不同类型的Resource,ResourceLoader则负责根据资源描述符(通常为字符串(数组),可带通配符),根据不同的情况,建立不同的Resource实例。

接口定义如下:

public interface ResourceLoader {

   /** Pseudo URL prefix for loading from the class path: "classpath:" */
   String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

   Resource getResource(String location);

      ClassLoader getClassLoader();

}

定义了加载资源的方法,并暴露ResourceLoader的类加载器,其实现类和子接口集成结构如下:

我们使用的ApplicationContex都继承ResourceLoader,其中DefaultResourceLoader的实现getResource如下,分三种情况进行资源的加载:

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);
         }
      }
   }

下面看在Spring构建ApplicationContext的时候,是如何使用ResourceLoader的,这里单摘出加载xml配置的部分代码。在AbstractBeanDefinitionReader以下方法:

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) {
         //支持通配符
         try {
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
         。。。。。
      else {
         // Can only load single resources by absolute URL.
         Resource resource = resourceLoader.getResource(location);
         。。。。
         }
         return loadCount;
      }
   }

@Override
//这里返回的就是ApplicationContext
   public ResourceLoader getResourceLoader() {
      return this.resourceLoader;
   }

结束

本文简单的分析了Spring的Resource框架,并单独摘出了Spring在加载bean定义的时使用Resource的代码,理解这点,为了解spring容器的启动过程打下一个小基础。本文依照spring源码写成,由于此部分相当简单,故很多部分(如AbstractResource的基本实现)都没有列出来。

时间: 2024-10-07 09:59:33

Spring之Resource的相关文章

Spring中@Resource、@controller注解的含义

@Resource 注解被用来激活一个命名资源(named resource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDI context中的一个对象. Spring确实支持使用@Resource通过JNDI lookup来解析对象,默认地,拥有与@Resource注解所提供名字相匹配的"bean name(bean名字)"的Spring管理对象会被注入. 在下面的例子中,Spring会向加了注解的setter方法传递bean名为"dataSour

Spring注解 @Resource和@Autowired

@Resource和@Autowired两者都是做bean的注入使用.其实@Resource并不是Spring的注解,他的包是javax.annotation.Resource 需要导入.但是Spring支持该注解的注入. 共同点 两者都可以写在字段和setter方法上.两者如果都写在字段上,就不需要写写setter方法. 如果将@requied或者@autowired写了set方法之上,则程序会走到set方法内部.但如果写在了field之上,则不会进入set方法当中. 不同点 @Autowir

Spring 注解 @Resource和@Autowired

@Resource和@Autowired两者都是做bean的注入使用. 其实@Resource并不是Spring的注解,他的包是javax.annotation.Resource 需要导入.但是Spring支持该注解的注入. 共同点:两者都可以写在字段和setter方法上.两者如果都写在字段上,就不需要写写setter方法. 不同点如下: 先来说一说@Autowired @Autowired为Spring提供的注解, 需导入Package:org.springframework.beans.fa

spring中@Resource注解的应用

前言,spring是一个非常优秀的框架,在依赖IOC编程方面,手工方式提供了两种方式注入Bean,XML配置和使用注解+自动扫描package的方式 [email protected]应用在字段上,则注入规则是: a.先使用字段名字匹配bean,查找到bean则注入,如果类型不匹配则此时有异常,注入失败 b.如果字段名字没有匹配到Bean则spring会尝试采用字段类型匹配,如果找打bean则注入,如果字段类型是接口则有可能会匹配到多个类型,则会抛出匹配到多个bean的异常. 注入失败. [em

Spring注解@Resource和@Autowired区别对比

@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入. 1.共同点 两者都可以写在字段和setter方法上.两者如果都写在字段上,那么就不需要再写setter方法. 2.不同点 (1)@Autowired @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.an

Spring的Resource 接口及其实现类

JDK 所提供的访问资源的类(如java.net.URL.File 等)并不能很好地满足各种底层资源的访问需求,比如缺少从类路径或者Web 容器的上下文中获取资源的操作类.有鉴于此,Spring 设计了一个Resource 接口,它为应用提供了更强的访问底层资源的能力.该接口拥有对应不同资源类型的实现类.先来了解一下Resource 接口的主要方法: boolean exists():资源是否存在: boolean isOpen():资源是否打开: URL getURL() throws IOE

Spring @Autowired,@Resource,@Required注解的用法和作用

Spring @Autowired,@Resource,@Required注解的用法和作用 Spring中 @Autowired标签与 @Resource标签 的区别

Spring 注解 @Resource和@Autowired(转)

鸣谢:http://my.oschina.net/u/216467/blog/205951 @Resource和@Autowired两者都是做bean的注入使用. 其实@Resource并不是Spring的注解,他的包是javax.annotation.Resource 需要导入.但是Spring支持该注解的注入. 共同点:两者都可以写在字段和setter方法上.两者如果都写在字段上,就不需要写写setter方法. 不同点如下: 先来说一说@Autowired @Autowired为Spring

【Java】Spring之Resource(三)

Java的各种URL前缀的标准类和标准处理程序不足以完全访问低级资源.例如,没有URL可用于访问需要从类路径或相对于a获取的资源的标准化实现 ServletContext.虽然可以为专用URL 前缀注册新的处理程序(类似于现有的前缀处理程序http:),但这通常非常复杂,并且URL接口仍然缺少一些理想的功能,例如检查资源是否存在的方法指着. Resource接口 Spring的Resource接口是一个更强大的接口,用于抽象对低级资源的访问.以下清单显示了Resource接口定义: 1 publ