Spring源码分析之资源定位(一)

最近看了Spring的初始化过程,这节讲述资源文件的定位。以FileSystemXmlApplicationContext为例来分析Spring的初始化过程。

1、FileSystemXmlApplicationContext的类结构图如图所示:

2、类图如下:

 3、类简介

DefaultResourceLoader: 资源定位类,可以通过一个String类型的path获取一个Resource,从而指向一个具体的文件。

                                              此类中最重要的方法是Resource getResource(String location),该方法间接调用getResourceByPath来获取Resource.

                                              FileSystemXmlApplicationContext覆写了父类DefaultResourceLoader中的getResourceByPath方法。

AbstractApplicationContext:refresh方法是入口方法也是核心方法,定义了生成ApplicationContext的实现步骤,使用了典型的模板方法模式,一些子步骤交给子类来实现。

                                                  obtainFreshBeanFactory方法可以获取一个真正的底层beanFactory,其中的refreshBeanFactory()和getBeanFactory()都是抽象方法

AbstractRefreshableApplicationContext: refreshBeanFactory是对父类AbstractApplicationContext中refreshBeanFactory的实现。

                                                                        createBeanFactory()是真正的创建工厂的方法,在此方法中创建了一个DefaultListableBeanFactory类型的工厂。

                                                                        此类的中的beanFactory属性保存了创建的工厂句柄。

AbstractRefreshableConfigApplicationContext:这个类的最主要的作用的保存配置文件的信息,主要存储在configLocations数组中。

                                                                                     此类提供了setConfigLocations和getConfigLocations方法。

AbstractXmlApplicationContext:最核心的方法是loadBeanDefinitions(DefaultListableBeanFactory beanFactory),此方法是对父类 AbstractRefreshableApplicationContext中方法的覆盖,此方法拉开了解析XML配置文件的序幕。

FileSystemXmlApplicationContext:最底层的构造方法 FileSystemXmlApplicationContext(String configLocations[], boolean refresh, ApplicationContext parent)

                                                               getResourceByPath方法是对DefaultResourceLoader中getResourceByPath的覆盖。

4、源码解析

(一)、构造一个FileSystemXmlApplicationContext的工厂,最终会调用的构造方法如下:

setConfigLocations:实际是调用从父类(AbstractRefreshableConfigApplicationContext)继承下来的方法,目的是把值保存在从父类(AbstractRefreshableConfigApplicationContext)继承下来的属性configLocations中。

refresh是核心方法,启动了资源定位、解析等一系统的后续过程。此refresh方法实际上调用从父类(AbstractApplicationContext)继承下来的refresh方法.
 (二)、refresh方法解析(AbstractApplicationContext)

 



 
 

refreshBeanFactory是核心方法,此方法的实现交由AbstractApplicationContext的子类AbstractRefreshableApplicationContext来实现。

(三)refreshBeanFactory方法解析(AbstractRefreshableApplicationContext)

 这个方法中最重要的方法是createBeanFactory()方法,这个方法是真正的创建工厂的方法,创建后的工厂保存在beanFactory属性中。

 

refreshBeanFactory方法的loadBeanDefinitions(beanFactory);方法启动了bean的注册过程.loadBeanDefinitions(DefaultListableBeanFactory defaultlistablebeanfactory)的实现交给子类AbstractXmlApplicationContext来完成.

(四)loadBeanDefinitions源码解析(AbstractXmlApplicationContext)

 

在loadBeanDefinitions方法中,生成了XmlBeanDefinitionReader,实际上bean的解析工作交给了beanDefinitionReader来处理.

在loadBeanDefinitions(DefaultListableBeanFactory beanFactory)中调用了重载的loadBeanDefinitions(XmlBeanDefinitionReader reader)方法,loadBeanDefinitions(XmlBeanDefinitionReader reader)源码解析(AbstractXmlApplicationContext),源码如下

在本方法中调用的getConfigLocations实际上调用的父类(AbstractRefreshableConfigApplicationContext)继承下来的方法,configLocations[]的值实际上是在(一)调用FileSystemXmlApplicationContext的构造方法时设置进去的( setConfigLocations(configLocations)).在这个方法中,我们可以看reader.loadBeanDefinitions(configLocations);启动了真正的解析动作.

(五)、public int loadBeanDefinitions(String locations[])源码解析(AbstractBeanDefinitionReader)

(AbstractBeanDefinitionReader是XmlBeanDefinitionReader的父类)

 

getResourceLoader()getResourceLoader()getResourceLoader()getResourceLoader()getResourceLoader()实际上获取的是new的工厂自身,因为在源码(四)中XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setResourceLoader(this);工厂本身也实现了DefaultResourceLoader.

Resource resource = resourceLoader.getResource(location);是获取转换后的资源,实际上间接调用了FileSystemXmlApplicationContext.getResourceByPath方法,这个方法会把一个String转化为一个Resource。

猜你喜欢

转载自hai19850514.iteye.com/blog/1825837