zoukankan      html  css  js  c++  java
  • Spring源码之XmlBeanDefinitionReader与Resource

    一、DefaultListableBeanFactory类,

    里面有一个成员变量beanDefinitionMap,Bean定义对象的Map, BeanDefinition就对应XML的属性配置

    /** Map of bean definition objects, keyed by bean name */
    	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
    

      

     二、上一篇讲到加载,读取xml的步骤。 

    1、ClassPathResource resource = new ClassPathSource("beans.xml");

    2、DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  //创建DefaultListableBeanFactory对象

    3、XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); //创建XmlBeanDefinitionReader 对象

    4、reader.loadBeanDefinitions(resource);  //加载bean的定义,bean来自资源文件。

     

    如何定位资源,解析资源? 

    下面进行具体分析:

    1、ClassPathResource resource = new ClassPathSource("beans.xml");

    首先进入ClassPathResource,进入构造函数

    进入第二个构造函数

    Assert翻译为中文为“断言”, 就是断定某一个实际的值就是自己预期想要得到的,如果不一样就抛出异常。

    Assert.notNull(path, "Path must not be null");

    如果path为空,就抛出异常

    4、reader.loadBeanDefinitions(resource);

    进入loadBeanDefinitions方法

    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    		return loadBeanDefinitions(new EncodedResource(resource));
    	}
    

      

    然后进入

    	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    		return loadBeanDefinitions(new EncodedResource(resource));
    	}
    
    	/**
    	 * Load bean definitions from the specified XML file.
    	 * @param encodedResource the resource descriptor for the XML file,
    	 * allowing to specify an encoding to use for parsing the file
    	 * @return the number of bean definitions found
    	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
    	 */
    	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());
    		}
    
    		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    		if (currentResources == null) {
    			currentResources = new HashSet<EncodedResource>(4);
    			this.resourcesCurrentlyBeingLoaded.set(currentResources);
    		}
    		if (!currentResources.add(encodedResource)) {
    			throw new BeanDefinitionStoreException(
    					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    		}
    		try {
    			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);
    		}
    		finally {
    			currentResources.remove(encodedResource);
    			if (currentResources.isEmpty()) {
    				this.resourcesCurrentlyBeingLoaded.remove();
    			}
    		}
    	}
    

      然后进入 doLoadBeanDefinitions(inputSource, encodedResource.getResource()); 方法。

       loadDocument用来加载生成Document对象,代表xml文档对应的Document对象。

    	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    			throws BeanDefinitionStoreException {
    		try {
    			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);
    		}
    	}
    

     loadDocument的方法如下:

        public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
                ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
    
            DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
            if (logger.isDebugEnabled()) {
                logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
            }
            DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
            return builder.parse(inputSource);
        }
    View Code


    registerBeanDefinitions方法
    /**
    	 * Register the bean definitions contained in the given DOM document.
    	 * Called by <code>loadBeanDefinitions</code>.
    	 * <p>Creates a new instance of the parser class and invokes
    	 * <code>registerBeanDefinitions</code> on it.
    	 * @param doc the DOM document
    	 * @param resource the resource descriptor (for context information)
    	 * @return the number of bean definitions found
    	 * @throws BeanDefinitionStoreException in case of parsing errors
    	 * @see #loadBeanDefinitions
    	 * @see #setDocumentReaderClass
    	 * @see BeanDefinitionDocumentReader#registerBeanDefinitions
    	 */
    	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    		documentReader.setEnvironment(this.getEnvironment());
    		int countBefore = getRegistry().getBeanDefinitionCount();
    		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    		return getRegistry().getBeanDefinitionCount() - countBefore;
    	}
    

      

     查看BeanDefinitionDocumentReader,

    里面有一个BeanDefinitionParserDelegate,真正实现xml解析就是这个类,类中定义了常量对应的xml属性

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

     

    doRegisterBeanDefinitions(root);

     

  • 相关阅读:
    个人案例分析
    软工结对作业
    交点问题
    C语言复习
    【软件工程】提问回顾与个人总结
    【技术博客】Arxiv的新Paper获取和机翻
    【技术博客】动态面包屑导航
    对对碰 -- 软工结对编程博客
    交点计数 -- 软工个人项目作业
    面向对象的程序设计-模块四课程总结
  • 原文地址:https://www.cnblogs.com/linlf03/p/11117079.html
Copyright © 2011-2022 走看看