Spring框架学习[IoC容器载入Bean资源文件](二)

2014-11-24 03:05:57 · 作者: · 浏览: 10
,关闭容器
  • destroyBeans(); closeBeanFactory();
  • } try {
  • //创建IoC容器 DefaultListableBeanFactory beanFactory = createBeanFactory();
  • beanFactory.setSerializationId(getId()); //对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等
  • customizeBeanFactory(beanFactory); //调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定//义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
  • loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) {
  • this.beanFactory = beanFactory; }
  • } catch (IOException ex) {
  • throw new ApplicationContextException(I/O error parsing bean definition source for + getDisplayName(), ex); }
  • }

    refresh()方法的作用是:在创建IoC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入。

    和refreshBeanFactory方法类似,载入Bean定义的方法loadBeanDefinitions也使用了委派模式,在AbstractRefreshableApplicationContext类中只定义了抽象方法,具体的实现调用子类容器中的方法实现。

    5.AbstractRefreshableApplicationContext子类的loadBeanDefinitions方法:

    AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现,AbstractXmlApplicationContext的主要源码如下:

    [java]
    1. public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { ……
    2. //实现父类抽象的载入Bean定义方法 @Override
    3. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器 //中去,容器使用该读取器读取Bean定义资源
    4. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的
    5. //祖先父类AbstractApplicationContext继承DefaultResourceLoader,因//此,容器本身也是一个资源加载器 beanDefinitionReader.setResourceLoader(this);
    6. //为Bean读取器设置SAX xml解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    7. //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 initBeanDefinitionReader(beanDefinitionReader);
    8. //Bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader);
    9. } //Xml Bean读取器加载Bean定义资源
    10. protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { //获取Bean定义资源的定位
    11. Resource[] configResources = getConfigResources(); if (configResources != null) {
    12. //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位 //的Bean定义资源
    13. reader.loadBeanDefinitions(configResources); }
    14. //如果子类中获取的Bean定义资源定位为空,则获取//FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源 String[] configLocations = getConfigLocations();
    15. if (configLocations != null) { //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位
    16. //的Bean定义资源 reader.loadBeanDefinitions(configLocations);
    17. } }
    18. //这里又使用了一个委托模式,调用子类的获取Bean定义资源定位的方法 //该方法在ClassPathXmlApplicationContext中进行实现,对于我们
    19. //举例分析源码的FileSystemXmlApplicationContext没有使用该方法 protected Resource[] getConfigResources() {
    20. return null; } ……
    21. }

      Xml Bean读取器(XmlBeanDefinitionReader)调用其父类AbstractBeanDefinitionReader的 reader.loadBeanDefinitions方法读取Bean定义资源。

      由于我们使用FileSystemXmlApplicationContext作为例子分析,因此getConfigResources的返回值为null,因此程序执行reader.loadBeanDefinitions(configLocations)分支。

      6. AbstractBeanDefinitionReader读取Bean定义资源:

      AbstractBeanDefinitionReader的loadBeanDefinitions方法源码如下:

      [java]
      1. //重载方法,调用下面的loadBeanDefinitions(String, Set );方法 public int loadBea