Spring源码之XmlBeanDefinitionReader与Resource
Posted on 2019-07-01 22:21 work hard work smart 阅读(399) 评论(0) 编辑 收藏 举报一、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的方法如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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); }
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);
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!