XmlWebApplicationContext加载bean XML源码解析

    XmlWebApplicationContext是我们开发中用到的最多的ApplicationContext实现,我对其源代码详细的分析,以便以后复习的时候可以参考。

public   class  XmlWebApplicationContext  extends  AbstractRefreshableWebApplicationContext {
    
/**  Default config location for the root context  */
    
public   static   final  String DEFAULT_CONFIG_LOCATION  =   " /WEB-INF/applicationContext.xml " ;
    
/**  Default prefix for building a config location for a namespace  */
    
public   static   final  String DEFAULT_CONFIG_LOCATION_PREFIX  =   " /WEB-INF/ " ;
    
/**  Default suffix for building a config location for a namespace  */
    
public   static   final  String DEFAULT_CONFIG_LOCATION_SUFFIX  =   " .xml " ;

    
protected   void  loadBeanDefinitions(DefaultListableBeanFactory beanFactory)  throws  IOException {
        
//  创建BeanDefinitionReader,从XML中读取bean信息的读取器
        XmlBeanDefinitionReader beanDefinitionReader  =   new  XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setResourceLoader(
this );
        beanDefinitionReader.setEntityResolver(
new  ResourceEntityResolver( this ));

        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }

    
protected   void  initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
    }

    
protected   void  loadBeanDefinitions(XmlBeanDefinitionReader reader)  throws  BeansException, IOException {
        String[] configLocations 
=  getConfigLocations();
        
if  (configLocations  !=   null ) {
            
for  ( int  i  =   0 ; i  <  configLocations.length; i ++ ) {
                reader.loadBeanDefinitions(configLocations[i]);
            }
        }
    }

    
protected  String[] getDefaultConfigLocations() {
        
if  (getNamespace()  !=   null ) {
            
return   new  String[] {DEFAULT_CONFIG_LOCATION_PREFIX  +  getNamespace()  +                              DEFAULT_CONFIG_LOCATION_SUFFIX};
        }
        
else  {
            
return   new  String[] {DEFAULT_CONFIG_LOCATION};
        }
    }

}

 loadBeanDefinitions(String location)方法是在AbstractBeanDefinitionReader中实现的:

     public   int  loadBeanDefinitions(String location)  throws  BeanDefinitionStoreException {
        ResourceLoader resourceLoader 
=  getResourceLoader();
        
if  (resourceLoader  ==   null ) {
            
throw   new  BeanDefinitionStoreException(
                    
" Cannot import bean definitions from location [ "   +  location  +   " ]: no ResourceLoader available " );
        }

        
if  (resourceLoader  instanceof  ResourcePatternResolver) {
            
//  Resource pattern matching available.
             try  {
                Resource[] resources 
=  ((ResourcePatternResolver) resourceLoader).getResources(location);
                
int  loadCount  =  loadBeanDefinitions(resources);
                
if  (logger.isDebugEnabled()) {
                    logger.debug(
" Loaded  "   +  loadCount  +   "  bean definitions from location pattern [ "   +  location  +   " ] " );
                }
                
return  loadCount;
            }
            
catch  (IOException ex) {
                
throw   new  BeanDefinitionStoreException(
                        
" Could not resolve bean definition resource pattern [ "   +  location  +   " ] " , ex);
            }
        }
        
else  {
            
// 根据给定的路径获得Resource.
            Resource resource  =  resourceLoader.getResource(location);
            //根据XML文件的bean信息加载bean属性
            
int  loadCount  =  loadBeanDefinitions(resource);
            
if  (logger.isDebugEnabled()) {
                logger.debug(
" Loaded  "   +  loadCount  +   "  bean definitions from location [ "   +  location  +   " ] " );
            }
            
return  loadCount;
        }
    }

这儿,public int loadBeanDefinitions(Resource resource)方法是在其子类XmlBeanDefinitionReader中实现的:


    
        //把XML中bean的配置信息注册到BeanDefinition中去
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        
return  getBeanFactory().getBeanDefinitionCount()  -  countBefore;
    }
public   int  loadBeanDefinitions(Resource resource)  throws  BeanDefinitionStoreException {
        
return  loadBeanDefinitions( new  EncodedResource(resource));
    }

    
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());
        }

        
try  {
            
// 过的XML配置文件的输入流
            InputStream inputStream  =  encodedResource.getResource().getInputStream();
            
try  {
                InputSource inputSource 
=   new  InputSource(inputStream);
                
if  (encodedResource.getEncoding()  !=   null ) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                
return  doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            
finally  {
                inputStream.close();
            }
        }
        
catch  (IOException ex) {
            
throw   new  BeanDefinitionStoreException(
                    
" IOException parsing XML document from  "   +  encodedResource.getResource(), ex);
        }
    }

    
protected   int  doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            
throws  BeanDefinitionStoreException {
        
try  {
            
int  validationMode  =  getValidationModeForResource(resource);
            Document doc 
=   this .documentLoader.loadDocument(
                    inputSource, 
this .entityResolver,  this .errorHandler, validationMode,  this .namespaceAware);
            
return  registerBeanDefinitions(doc, resource);
        }
        
catch  (BeanDefinitionStoreException ex) {
            
throw  ex;
        }
        
catch  (ParserConfigurationException ex) {
            
throw   new  BeanDefinitionStoreException(
                    
" Parser configuration exception parsing XML from  "   +  resource, ex);
        }
        
catch  (SAXParseException ex) {
            
throw   new  BeanDefinitionStoreException(
                    
" Line  "   +  ex.getLineNumber()  +   "  in XML document from  "   +  resource  +   "  is invalid " , ex);
        }
        
catch  (SAXException ex) {
            
throw   new  BeanDefinitionStoreException( " XML document from  "   +  resource  +   "  is invalid " , ex);
        }
        
catch  (IOException ex) {
            
throw   new  BeanDefinitionStoreException( " IOException parsing XML document from  "   +  resource, ex);
        }
        
catch  (Throwable ex) {
            
throw   new  BeanDefinitionStoreException( " Unexpected exception parsing XML document from  "   +  resource, ex);
        }
    }

    
public   int  registerBeanDefinitions(Document doc, Resource resource)  throws  BeanDefinitionStoreException {
        
//使用 XmlBeanDefinitionParser读取配置文件,但是现在已经反对使用此类
         if  ( this .parserClass  !=   null ) {
            XmlBeanDefinitionParser parser 
=
                    (XmlBeanDefinitionParser) BeanUtils.instantiateClass(
this .parserClass);
            
return  parser.registerBeanDefinitions( this , doc, resource);
        }
        
//Spring2.0以后都用BeanDefinitionDocumentReader来读取
        BeanDefinitionDocumentReader documentReader  =  createBeanDefinitionDocumentReader();
        
int  countBefore  =  getBeanFactory().getBeanDefinitionCount();

BeanDefinitionDocumentReader有一个默认的实现类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);

        preProcessXml(root);
        parseBeanDefinitions(root, delegate);
        postProcessXml(root);
    }
    //从根节点开始读取bean配置信息,并把属性一一复制到BeanDefinition中去
    
protected   void  parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        
if  (delegate.isDefaultNamespace(root.getNamespaceURI())) {
            NodeList nl 
=  root.getChildNodes();
            
for  ( int  i  =   0 ; i  <  nl.getLength(); i ++ ) {
                Node node 
=  nl.item(i);
                
if  (node  instanceof  Element) {
                    Element ele 
=  (Element) node;
                    String namespaceUri 
=  ele.getNamespaceURI();
                    
if  (delegate.isDefaultNamespace(namespaceUri)) {
                        parseDefaultElement(ele, delegate);
                    }
                    
else  {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        
else  {
            delegate.parseCustomElement(root);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值