谈一谈我对Spring Resource的理解

6,415 阅读3分钟

一、什么是Resource

当我们学习Spring时,我们总会在xml中对bean进行声明,然后再通过下面的代码片段来获取bean。代码如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Context {

  public static void main(String[] args) {
    
    ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring.xml");//1、加载配置文件
    System.err.println(ctx.getBean("stu").toString());//2、通过配置文件获取一个bean并打印

   }
}

上面第一行代码加载了一个资源文件Spring.xml,这个资源文件在Spring中属于Resource的一种。这样讲,Spring把各种类型的文件,二进制流都称之为Resource,只不过对于Spring开发者来说,Resource大多都是xml文件。

Resource是一个接口,接口里边定义了非常多关于文件的操作策略,比如

  • exists():判断资源是否存在
  • getURL():获取资源的URL
  • getFilename():获取资源的名称
  • ......(方法非常多,我就不一一列举了)

Resource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。Resource 接口本身没有提供访问任何底层资源的实现逻辑,针对不同的底层资源,Spring 将会提供不同的 Resource 实现类,不同的实现类负责不同的资源访问逻辑。

非常重要的一点,这也是Spring Resource设计最美妙的地方,那就是Spring 在Resource资源处理上采用啦策略模式,这也是我为什么上面把Resource接口中的方法称之为策略的原因了!

如果还不了解Java 策略模式的朋友请先自行学习!

二、Spring Resource接口类结构图

为了更好地理解,在这里我先放一张策略模式的UML图,它的具体内容本文不讲。

好了!图片放上去了,那么策略模式Resource体系上如何体现出来呢?

  • 1、Resource接口相当于我们的策略
  • 2、下面所有的实现类,包括AbstractResource在内都属于我们的具体策略实现
  • 3、你可能要问,那么我们的context角色到哪里去了呢?哈哈,做生意不能忘了我们的老本啊!它就是我们的IOC容器ApplicationContext,它是我们策略模式中最最最具有决策能力的老大了

至于为什么容器就可以处理我们的Resource,我接下去会说到!

很明显,Resource是资源的最高抽象,通常我们的应用程序不是都从classpath下去加载我们的xml文件,我们也可以通过一个URL,URI,InputStream等方式获取一个资源,这就是Spring把资源的获取方式和资源的定义之间解耦了!

三、ResourceLoader接口

  • ResourceLoader:该接口实现类的实例可以获得一个 Resource 实例。。

ResourceLoader 接口里有如下方法:

  • Resource getResource(String location):该接口仅包含这个方法,该方法用于返回一个 Resource 实例。

ApplicationContext 的实现类都实现 ResourceLoader 接口,而该接口又返回一个Resource实例,因此 ApplicationContext 可用于直接获取 Resource 实例,这也是为什么容器就可以处理Resource的原因!

四、策略模式在Spring中使用有什么优势

Spring 应用需要进行资源访问时,实际上并不需要直接使用 Resource 实现类,而是调用 ApplicationContext 实例的 getResource() 方法来获得资源,ApplicationContext 将会负责选择 Resource 的实现类,也就是确定具体的资源访问策略,从而将应用程序和具体的资源访问策略分离开来。

既然有那么多的优势,下面就在来解释我们上面的第一段代码,为什么要使用ClassPathXmlApplicationContext这个类来对资源进行加载?

我们都知道,在容器ApplicationContext下有很多的实现,比如FileSystemXmlApplicationContext,ClassPathXmlApplicationContext,XmlWebApplicationContext,而且我们加载配置文件的方式通常也是使用它们来进行加载,在Spring中,ApplicationContext的实现类顾名思义也是对应了我们Resource接口的一些实现策略,比如ClassPathResource,FileSystemResource等。