spring 源码分析--IOC容器初始化五

上面完成了对资源的定位工作,接下去就是解析资源的内容了,接着第四节的第一个函数说,这一节主要完成将xml文件解析为DOM对象,函数的职责很单一。

 

 

  1.2.2.1.1.3.1.1.3 loadBeanDefinitions(EncodedResource encodedResource): 方法定义在 XmlBeanDefinitionReader 类中,用以装载以 xml 格式定义的 bean

====================================================================

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {

    Assert.notNull (encodedResource, “EncodedResource must not be null” );

    if ( logger .isInfoEnabled()) {

logger .info( “Loading XML bean definitions from “ + encodedResource.getResource());

    }

// 使用 ThreadLocal 解决多线程问题。

Set currentResources = (Set ) this . resourcesCurrentlyBeingLoaded .get();

    if (currentResources == null ) {

       currentResources = new HashSet (4);

       this . resourcesCurrentlyBeingLoaded .set(currentResources) ;

    }

// 放置资源。

    if (!currentResources.add(encodedResource) ) {

       throw new BeanDefinitionStoreException(

       “Detected recursive loading of “ + encodedResource + ” – check your import definitions!” );

    }

    try {

    // 这里通过 Resource 得到 InputStream IO

       InputStream inputStream = encodedResource.getResource().getInputStream();

       try {

       // InputStream 中得到 XML 的解析源  

           InputSource inputSource = new InputSource(inputStream);

           if (encodedResource.getEncoding() != null ) {

               inputSource.setEncoding(encodedResource.getEncoding());

           }

       // 这里是具体的解析和注册过程

           return doLoadBeanDefinitions(inputSource, encodedResource.getResource()) ;

           }

           finally {

           // 关闭从 Resource 中得到的 IO  

              inputStream.close();

           }

       }

       catch (IOException ex) {

           throw new BeanDefinitionStoreException(

                  “IOException parsing XML document from “ + encodedResource.getResource(), ex);

       }

       finally {

           currentResources.remove(encodedResource);

           if (currentResources.isEmpty()) {

              this . resourcesCurrentlyBeingLoaded .set( null ) ;

           }

       }

    }

====================================================================

然后进入到具体的解析过程,实际真正从 xml 中装载 bean 的地方:即函数;

(从上面的过程可以知道,接下去的工作都会在下面的函数里完成,所以先做一个假设:2=1.2.2.1.1.3.1.1.3.1)

 

2. doLoadBeanDefinitions(inputSource, encodedResource.getResource())

该函数定义在 XmlBeanDefinitionReader

====================================================================

protected int doLoadBeanDefinitions (InputSource inputSource, Resource resource)

throws BeanDefinitionStoreException {

    try {

    // 通过解析得到 DOM ,然后完成 bean IOC 容器中的注册

       int validationMode = getValidationModeForResource(resource);

       Document doc = this . documentLoader .loadDocument(

              inputSource, getEntityResolver(), this . errorHandler , validationMode, isNamespaceAware());

       return registerBeanDefinitions(doc, resource) ;

    } catch (BeanDefinitionStoreException ex) {

           throw ex;

    } catch (SAXParseException ex) {

              throw new XmlBeanDefinitionStoreException(resource.getDescription(),

                     “Line “ + ex.getLineNumber() + ” in XML document from “ + resource + ” is invalid” , ex);

    } catch (SAXException ex) {

              throw new XmlBeanDefinitionStoreException(resource.getDescription(),

                  “XML document from “ + resource + ” is invalid” , ex);

    } catch (ParserConfigurationException ex) {

              throw new BeanDefinitionStoreException(resource.getDescription(),

                     “Parser configuration exception parsing XML from “ + resource, ex);

    } catch (IOException ex) {

              throw new BeanDefinitionStoreException(resource.getDescription(),

             “IOException parsing XML document from “ + resource, ex);

    } catch (Throwable ex) {

           throw new BeanDefinitionStoreException(resource.getDescription(),

                  “Unexpected exception parsing XML document from “ + resource, ex);

    }

}

====================================================================

 

 

2.1 registerBeanDefinitions(doc, resource) 我们看到先把定义文件解析为 DOM 对象,然后进行具体的注册过程:

====================================================================

public int registerBeanDefinitions (Document doc, Resource resource) throws BeanDefinitionStoreException {

// Support old XmlBeanDefinitionParser SPI for backwards-compatibility.

// 这里定义解析器,使用 XmlBeanDefinitionParser 来解析 xml 方式的 bean 定义文件

// 现在的版本不用这个解析器了,使用的是 XmlBeanDefinitionReader 

       if ( this . parserClass != null ) {

           XmlBeanDefinitionParser parser =

(XmlBeanDefinitionParser ) BeanUtils.instantiateClass ( this . parserClass );

           return parser.registerBeanDefinitions( this , doc, resource) ;

       }

// Read document based on new BeanDefinitionDocumentReader SPI.

// 具体的注册过程 , 首先得到 DefaultBeanDefinitionDocumentReader , 来处理 xml

// bean 定义文件

BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();

// 得到当前容器中 bean 的数量,由 前面 可知,这里的 Registry 实际上是一个 // DefaultListableBeanFactory 里实际上是得到 DefaultListableBeanFactory // 类中字段 beanDefinitionMap 的大小。

       int countBefore = getRegistry().getBeanDefinitionCount();

documentReader.registerBeanDefinitions(doc, createReaderContext(resource)) ;

       return getRegistry().getBeanDefinitionCount() – countBefore;

    }

====================================================================

 

 

 

²2.1.1 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)): 在类

DefaultBeanDefinitionDocumentReader 中定义

====================================================================

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {

    this . readerContext = readerContext;

    logger .debug( “Loading bean definitions” );

    Element root = doc.getDocumentElement();

    BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);

// 允许子类继承预处理 xml ,默认实现为空。

preProcessXml(root);

    parseBeanDefinitions(root, delegate);

// 允许子类继承进一步处理 xml ,默认实现为空。

    postProcessXml(root);

    }

====================================================================

 

 

本站支持 pay for your wishes

    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/iteye_17060/article/details/81966272
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞