2019独角兽企业重金招聘Python工程师标准>>>
前言
本文转自“天河聊技术”微信公众号
接着上一篇文章的bean定义解析继续
正文
上一次解析到这个方法org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)这行代码
// 加载bean定义 return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
// 加载xml文档 Document doc = doLoadDocument(inputSource, resource);
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception { return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware()); }
isNamespaceAware() 返回XML解析器是否应该具有XML名称空间
进入这个方法org.springframework.beans.factory.xml.XmlBeanDefinitionReader#getValidationModeForResource
protected int getValidationModeForResource(Resource resource) { int validationModeToUse = getValidationMode(); if (validationModeToUse != VALIDATION_AUTO) { return validationModeToUse; } int detectedMode = detectValidationMode(resource); if (detectedMode != VALIDATION_AUTO) { return detectedMode; } // Hmm, we didn't get a clear indication... Let's assume XSD, // since apparently no DTD declaration has been found up until // detection stopped (before finding the document's root tag). // 如果没有解析到xml验证模式就采用XSD验证 return VALIDATION_XSD; }
进入这一行的这个方法
int detectedMode = detectValidationMode(resource);
protected int detectValidationMode(Resource resource) { if (resource.isOpen()) { throw new BeanDefinitionStoreException( "Passed-in Resource [" + resource + "] contains an open stream: " + "cannot determine validation mode automatically. Either pass in a Resource " + "that is able to create fresh streams, or explicitly specify the validationMode " + "on your XmlBeanDefinitionReader instance."); } InputStream inputStream; try { inputStream = resource.getInputStream(); } catch (IOException ex) { throw new BeanDefinitionStoreException( "Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " + "Did you attempt to load directly from a SAX InputSource without specifying the " + "validationMode on your XmlBeanDefinitionReader instance?", ex); } try { return this.validationModeDetector.detectValidationMode(inputStream); } catch (IOException ex) { throw new BeanDefinitionStoreException("Unable to determine validation mode for [" + resource + "]: an error occurred whilst reading from the InputStream.", ex); } }
进入这一行的这个方法
return this.validationModeDetector.detectValidationMode(inputStream);
org.springframework.util.xml.XmlValidationModeDetector#detectValidationMode
public int detectValidationMode(InputStream inputStream) throws IOException { // Peek into the file to look for DOCTYPE. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try { boolean isDtdValidated = false; String content; while ((content = reader.readLine()) != null) { // 跳过 注释 content = consumeCommentTokens(content); if (this.inComment || !StringUtils.hasText(content)) { continue; } // 是否有DOCTYPE声明 if (hasDoctype(content)) { isDtdValidated = true; break; } // 判断文件是否是以xml标记开头 if (hasOpeningTag(content)) { // End of meaningful data... break; } } // 如果找到了DOCTYPE声明就启用DTD验证,如果没有就启用XSD验证 return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
} catch (CharConversionException ex) { // Choked on some character encoding... // Leave the decision up to the caller. 异常spring就会去猜测一种解析类型去解析 return VALIDATION_AUTO; } finally { reader.close(); } }
返回到这个方法
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadDocument
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception { return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware()); }
loadDocument()加载xmnl文档,底层是java的api
返回到这个方法
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions
// 注册bean定义 return registerBeanDefinitions(doc, resource);
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { // 创建bean定义阅读器 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); // 注册bean定义之前先创建XmlReaderContext documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
进入这行代码
// 注册bean定义之前先创建 documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
进入这个方法
public XmlReaderContext createReaderContext(Resource resource) { return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, getNamespaceHandlerResolver()); }
public NamespaceHandlerResolver getNamespaceHandlerResolver() { if (this.namespaceHandlerResolver == null) { this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver(); } return this.namespaceHandlerResolver; }
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() { ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader()); return new DefaultNamespaceHandlerResolver(cl); }
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) { this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION); }
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";
可以看到是从这个路径下加载的spring.handlers
返回到这个方法
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions这一行代码
// 注册bean定义之前先创建 documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
进入这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
@Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); // 获取xml文档根节点 Element root = doc.getDocumentElement(); // 从xml文件中解析bean定义 doRegisterBeanDefinitions(root); }
进入这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
protected void doRegisterBeanDefinitions(Element root) {
// 加载bean定义 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); // 如果根节点是命名空间 http://www.springframework.org/schema/beans if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // 解析环境配置文件 if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } }
进入这个方法
protected BeanDefinitionParserDelegate createDelegate( XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) { // bean定义解析委托 BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); // bean定义默认配置 delegate.initDefaults(root, parentDelegate); return delegate; }
进入这个方法
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#initDefaults(org.w3c.dom.Element, org.springframework.beans.factory.xml.BeanDefinitionParserDelegate)
public void initDefaults(Element root, @Nullable BeanDefinitionParserDelegate parent) { // 解析默认的bean定义解析配置 populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root); // 触发默认的bean定义事件 this.readerContext.fireDefaultsRegistered(this.defaults); }
进入这个方法
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#populateDefaults
// 解析beans标签 protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable DocumentDefaultsDefinition parentDefaults, Element root) { // 解析default标签值 是否是default-lazy-init,默认值是false,父配置文件的属性会覆盖子配置文件的属性 String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { // Potentially inherited from outersections, otherwise falling back to false. lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE); } defaults.setLazyInit(lazyInit); // default-merge 是否是这个值,默认值是false String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE); if (DEFAULT_VALUE.equals(merge)) { // Potentially inherited from outer sections, otherwise falling back to false. merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE); } defaults.setMerge(merge); // default-autowire 是否是这个值,默认值是no String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE); if (DEFAULT_VALUE.equals(autowire)) { // Potentially inherited from outer sections, otherwise falling back to 'no'. autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE); } defaults.setAutowire(autowire); // default-autowire-candidate 是否最为候选bean被自动注入 if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) { defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates()); } // default-init-method if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) { defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setInitMethod(parentDefaults.getInitMethod()); } // default-destroy-method if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) { defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setDestroyMethod(parentDefaults.getDestroyMethod()); } defaults.setSource(this.readerContext.extractSource(root)); }
返回到这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions这一行
// 解析环境配置文件 if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
下片文章继续。
最后
本次介绍到这里,以上内容仅供参考。