zoukankan      html  css  js  c++  java
  • BeanDefinition的Resource定位——3

    1.我们重点看看AbstractRefreshableApplicationContextrefreshBeanFactory方法的实现,这个refreshBeanFactoryFileSystemXmlApplicationContext构造函数中的refresh调用。在这个方法中,通过createBeanFactory构建了一个IoC容器供ApplicationContext使用。这个IoC容器就是我们前面提到过的DefaultListableBeanFactory,同时,它启动了loadBeanDefinitions来载入BeanDefinition,这个过程和前面以编程的方式来使用IoC容器(XmlBeanFacoty)的过程非常类似。

     1 protected final void refreshBeanFactory() throws BeansException {
     2         // 这里判断,如果已经建立了BeanFactory,则销毁并关闭该BeanFactory
     3         if (hasBeanFactory()) {
     4             destroyBeans();
     5             closeBeanFactory();
     6         }
     7         // 这里是创建并设置持有的DefaultListableBeanFactory的地方
     8         // 同时调用loadBeanDefinitions载入BeanDefinition的信息
     9         try {
    10             DefaultListableBeanFactory beanFactory = createBeanFactory();
    11             beanFactory.setSerializationId(getId());
    12             customizeBeanFactory(beanFactory);
    13             loadBeanDefinitions(beanFactory);
    14             synchronized (this.beanFactoryMonitor) {
    15                 this.beanFactory = beanFactory;
    16             }
    17         }
    18         catch (IOException ex) {
    19             throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    20         }
    21     }
    AbstractRefreshableApplicationContext对容器的初始化
    1 // 这就是在上下文中创建DefaultListableBeanFactory的地方,而getInternalParentBeanFacoty()
    2     // 的具体实现可以
    3     // 查看AbstractApplicationContext中的实现,会根据容器已有的双亲IoC容器的信息来生成
    4     // DefaultListableBeanFactory的双亲IoC容器
    5     protected DefaultListableBeanFactory createBeanFactory() {
    6         return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    7     }
    createBeanFactory
    1 // 这里是使用BeanDefinitionReader载入Bean定义的地方,因为允许有多种载入方式,虽然用得
    2     // 最多的事XML定义的形式,这里通过一个抽象函数把具体的实现委托给子类来完成
    3     protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
    4             throws BeansException, IOException;
    loadBeanDefinitions
     1 // 对于取得Resource的具体过程,我们可以看看DefaultResourceLoader是怎样完成的
     2     public Resource getResource(String location) {
     3         Assert.notNull(location, "Location must not be null");
     4         // 
     5         if (location.startsWith("/")) {
     6             return getResourceByPath(location);
     7         }
     8         else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
     9             return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
    10         }
    11         else {
    12             try {
    13                 // Try to parse the location as a URL...
    14                 URL url = new URL(location);
    15                 return new UrlResource(url);
    16             }
    17             catch (MalformedURLException ex) {
    18                 // No URL -> resolve as resource path.
    19                 return getResourceByPath(location);
    20             }
    21         }
    22     }
    getResource

     2.前面我们看到的getResourceByPath被子类FileSystemXmlApplicationContext实现,这个方法返回的是一个FileSystemResource对象,通过这个对象,Spring可以进行相关的I/O操作,完成BeanDefinition的定位。分析到这里已经一目了然,它实现的就是对path进行解析,然后生成一个FileSystemResource对象并返回,代码清单如下所示。

    1 protected Resource getResourceByPath(String path) {
    2         if (path != null && path.startsWith("/")) {
    3             path = path.substring(1);
    4         }
    5         return new FileSystemResource(path);
    6     }
    FileSystemXmlApplicationContext生成FileSystemResource对象

    3.如果是其他的ApplicationContext,那么会对应生成其他种类的Resource,比如ClassPathResource、ServletContextResource等。

    4.关于Spring中Resource的种类,可以在图1的Resource类的继承关系中了解。作为接口Resource定义了许多与I/O相关的操作,这些操作也都可以从图1种的Resource的接口定义中看到。这些接口对不同的Resource实现代表着不同的意义,是Resource的实现需要考虑的。Resource接口的实现在Spring中的设计如图1所示。

    图1 Resource的定义和继承关系

    5.从图1中我们可以看到Resource的定位和它的继承关系,通过对前面的实现原理的分析,我们以FileSystemXmlApplicationContext的实现为例子,了解Resource定位问题的解决方案,即以FileSystem方式存在的Resource的定位实现。

    6.在BeanDefinition定位完成的基础上,就可以通过返回的Resource对象来进行BeanDefinition的载入了。

    7.在定位过程完成以后,为BeanDefinition的载入创造了I/O操作的条件,但是具体的数据还没有开始读入。这些数据的读入将在下面的BeanDefinition的载入和解析中来完成

    8.任然以水桶为例子,这里就像用水桶去打水,要先找到水源。这里完成对Resource的定位,就类似于水源已经找到了,下面就是打水的过程了,类似于把找到的水装到水桶里的过程。找水不简单,但是与打水相比,我们发现打水更需要技巧。

  • 相关阅读:
    JAVA中HashMap相关知识的总结(一)
    linux进阶之路(三):vi/vim编辑器
    linux进阶之路(二):linux文件目录
    linux进阶之路(一):linux入门
    linux:lrzsz安装
    一:阿里云服务器使用及后台环境搭建
    第二篇:线程七种状态
    Git log
    redis3.0 集群实战3
    详解Linux chgrp和chown命令的用法
  • 原文地址:https://www.cnblogs.com/duffy/p/3979282.html
Copyright © 2011-2022 走看看