一. 理论背景
在 Spring 框架中,读取配置文件是一个常见的需求。为了满足这一需求,Spring 提供了一个名为 Resource 的接口。Resource 接口定义了访问资源的基本方法,是一个抽象的资源访问策略。
Resource 接口的主要方法包括:
getInputStream()
: 定位并打开资源,返回资源的输入流。每次调用都会返回一个新的输入流,调用者需确保关闭输入流。exists()
: 判断资源是否存在。isOpen()
: 检查资源是否已经打开。如果资源不能多次读取,每次读取后应显式关闭,以防止资源泄漏。getDescription()
: 返回资源的描述信息,通常用于资源处理出错时提供详细信息,如全限定文件名或实际 URL。getFile()
: 返回资源对应的 File 对象。getURL()
: 返回资源对应的 URL 对象。
Resource 接口本身不包含具体的资源访问实现逻辑,而是由不同的实现类来提供。Spring 为 Resource 接口提供了多种实现类,每种实现类负责不同的资源访问逻辑。
Resource 接口与策略模式
Resource 接口是策略模式的一个典型应用。Resource 接口定义了资源访问策略,但具体的实现策略由不同的实现类提供。客户端程序只需与 Resource 接口耦合,无需关心底层的具体实现,从而实现了资源访问策略的灵活切换。
Spring 为 Resource 接口提供的实现类包括:
UrlResource
: 访问网络资源。ClassPathResource
: 访问类加载路径中的资源。FileSystemResource
: 访问文件系统中的资源。ServletContextResource
: 访问相对于 ServletContext 路径的资源。InputStreamResource
: 访问输入流资源。ByteArrayResource
: 访问字节数组资源。
这些实现类为不同的资源类型提供了便捷的访问方式,使客户端程序能够轻松地访问各种资源。
二. 源码分析
通过跟踪 ClassPathXmlApplicationContext
对象的创建过程,可以深入了解 Spring 如何使用 Resource 接口及其实现类来实现策略模式。
策略模式的优势在于,当 Spring 应用需要访问资源时,并不需要直接使用 Resource 实现类,而是通过 ApplicationContext
实例的 getResource()
方法来获取资源。ApplicationContext 会负责选择合适的 Resource 实现类,即确定具体的资源访问策略,从而将应用程序与具体的资源访问策略分离,体现了策略模式的优势。
1 //1. 根据传入的配置文件地址,创建容器对象 ClassPathXmlApplicationContext
2 public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
3 this(new String[] {configLocation}, true, null);
4 }
2 //2. 1中代码调用到此处,此处调用父类构造函数 ClassPathXmlApplicationContext
3 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
4 super(parent);
5 setConfigLocations(configLocations);
6 if (refresh) {
7 refresh();
8 }
9 }