refresh()方法的作用是:在创建IoC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入。
和refreshBeanFactory方法类似,载入Bean定义的方法loadBeanDefinitions也使用了委派模式,在AbstractRefreshableApplicationContext类中只定义了抽象方法,具体的实现调用子类容器中的方法实现。
5.AbstractRefreshableApplicationContext子类的loadBeanDefinitions方法:
AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现,AbstractXmlApplicationContext的主要源码如下:
[java]- public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { ……
- //实现父类抽象的载入Bean定义方法 @Override
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器 //中去,容器使用该读取器读取Bean定义资源
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的
- //祖先父类AbstractApplicationContext继承DefaultResourceLoader,因//此,容器本身也是一个资源加载器 beanDefinitionReader.setResourceLoader(this);
- //为Bean读取器设置SAX xml解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
- //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 initBeanDefinitionReader(beanDefinitionReader);
- //Bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader);
- } //Xml Bean读取器加载Bean定义资源
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { //获取Bean定义资源的定位
- Resource[] configResources = getConfigResources(); if (configResources != null) {
- //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位 //的Bean定义资源
- reader.loadBeanDefinitions(configResources); }
- //如果子类中获取的Bean定义资源定位为空,则获取//FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源 String[] configLocations = getConfigLocations();
- if (configLocations != null) { //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
- //的Bean定义资源 reader.loadBeanDefinitions(configLocations);
- } }
- //这里又使用了一个委托模式,调用子类的获取Bean定义资源定位的方法 //该方法在ClassPathXmlApplicationContext中进行实现,对于我们
- //举例分析源码的FileSystemXmlApplicationContext没有使用该方法 protected Resource[] getConfigResources() {
- return null; } ……
- }
Xml Bean读取器(XmlBeanDefinitionReader)调用其父类AbstractBeanDefinitionReader的 reader.loadBeanDefinitions方法读取Bean定义资源。
由于我们使用FileSystemXmlApplicationContext作为例子分析,因此getConfigResources的返回值为null,因此程序执行reader.loadBeanDefinitions(configLocations)分支。
6. AbstractBeanDefinitionReader读取Bean定义资源:
AbstractBeanDefinitionReader的loadBeanDefinitions方法源码如下:
[java]- //重载方法,调用下面的loadBeanDefinitions(String, Set
);方法 public int loadBea
- //重载方法,调用下面的loadBeanDefinitions(String, Set