欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-02 16:27:49
...

上面完成了对资源的定位工作,接下去就是解析资源的内容了,接着第四节的第一个函数说,这一节主要完成将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