前言node
本文转自“天河聊技术”微信公众号spring
上次介绍了bean定义解析部分的xml验证和<beans>标签默认属性解析,接着上次解析节奏开始。缓存
正文微信
上一次介绍到这个方法app
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions的这行代码less
// bean定义解析 parseBeanDefinitions(root, this.delegate);
进入这个方法ide
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitionsui
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 根节点是不是命名空间 http://www.springframework.org/schema/beans if (delegate.isDefaultNamespace(root)) { 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; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
进入到这个方法this
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElementspa
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { // import 标签解析 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // alias else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } // bean else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 内部beans标签 doRegisterBeanDefinitions(ele); } }
// import 标签解析 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); }
进入这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#importBeanDefinitionResource
protected void importBeanDefinitionResource(Element ele) { // resource 解析属性 String location = ele.getAttribute(RESOURCE_ATTRIBUTE); if (!StringUtils.hasText(location)) { getReaderContext().error("Resource location must not be empty", ele); return; } // Resolve system properties: e.g. "${user.dir}" 占位符系统属性解析 location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location); Set<Resource> actualResources = new LinkedHashSet<>(4); // Discover whether the location is an absolute or relative URI 判断路径是相对仍是绝对 boolean absoluteLocation = false; try { absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute(); } catch (URISyntaxException ex) { // cannot convert to an URI, considering the location relative // unless it is the well-known Spring prefix "classpath*:" } // Absolute or relative? if (absoluteLocation) { // 若是是绝地路径 try { int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources); if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]"); } } catch (BeanDefinitionStoreException ex) { getReaderContext().error( "Failed to import bean definitions from URL location [" + location + "]", ele, ex); } } else { // No URL -> considering resource location as relative to the current file. try { int importCount; Resource relativeResource = getReaderContext().getResource().createRelative(location); if (relativeResource.exists()) { // 调用bean定义加载 importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); actualResources.add(relativeResource); } else { String baseLocation = getReaderContext().getResource().getURL().toString(); // 调用bean定义加载 importCount = getReaderContext().getReader().loadBeanDefinitions( StringUtils.applyRelativePath(baseLocation, location), actualResources); } if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]"); } } catch (IOException ex) { getReaderContext().error("Failed to resolve current resource location", ele, ex); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]", ele, ex); } } Resource[] actResArray = actualResources.toArray(new Resource[0]); // 触发import bean定义解析完毕 getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele)); }
返回到这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement的这行代码
// alias else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); }
进入到这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processAliasRegistration
protected void processAliasRegistration(Element ele) { // 获取name属性值 String name = ele.getAttribute(NAME_ATTRIBUTE); // 获取alias属性值 String alias = ele.getAttribute(ALIAS_ATTRIBUTE); boolean valid = true; if (!StringUtils.hasText(name)) { getReaderContext().error("Name must not be empty", ele); valid = false; } if (!StringUtils.hasText(alias)) { getReaderContext().error("Alias must not be empty", ele); valid = false; } if (valid) { try { // 从xml读取上下文中获取bean定义注册器注册别名 getReaderContext().getRegistry().registerAlias(name, alias); } catch (Exception ex) { getReaderContext().error("Failed to register alias '" + alias + "' for bean with name '" + name + "'", ele, ex); } // 触发别名已注册事件 getReaderContext().fireAliasRegistered(name, alias, extractSource(ele)); } }
找到这行代码
// 从xml读取上下文中获取bean定义注册器注册别名 getReaderContext().getRegistry().registerAlias(name, alias);
进入这个方法
org.springframework.context.support.GenericApplicationContext#registerAlias
@Override public void registerAlias(String beanName, String alias) { // 注册别名 this.beanFactory.registerAlias(beanName, alias); }
进入到这个方法
org.springframework.core.SimpleAliasRegistry#registerAlias
@Override public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); synchronized (this.aliasMap) { // 若是别名和名字一致,从缓存map中删除别名 if (alias.equals(name)) { this.aliasMap.remove(alias); } else { String registeredName = this.aliasMap.get(alias); if (registeredName != null) { // name值和alias值不能同样 if (registeredName.equals(name)) { // An existing alias - no need to re-register return; } // alias名不能覆盖name名值 if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } // 检查注册的别名是否已存在 checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); } } }
返回到这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processAliasRegistration这行代码
// 触发别名已注册事件 getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
返回到这个方法
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement这行代码<bean>标签解析
// bean else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); }
下次继续。
最后
本次介绍到这里,以上内容仅供参考。