private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}

可以看出主要对(import,  alias, bean, beans进行解析)

IMPORT_ELEMENT
ALIAS_ELEMENT
BEAN_ELEMENT
NESTED_BEANS_ELEMENT
在上一篇文章DefaultListableBeanFactory只是保存一些bean解析出后的信息的注册基本信息到
beanDefinitionMap 
/** Resolver to use for checking if a bean definition is an autowire candidate */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); /** Map from dependency type to corresponding autowired value */
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16); /** Map of bean definition objects, keyed by bean。 name BeanDefinition主要是保存Bean 的名字,class 依赖等待信息*/
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
/** Map of singleton bean names keyed by bean class */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** Map of non-singleton bean names keyed by bean class */
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>();

 Bean解析:

    /**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//根据ele解析出所包含的所有信息
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.注册bdHold到beanDefinationMap
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
/**
* Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
* if there were errors during parse. Errors are reported to the
* {@link org.springframework.beans.factory.parsing.ProblemReporter}.
*/
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
} /**
* Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
* if there were errors during parse. Errors are reported to the
* {@link org.springframework.beans.factory.parsing.ProblemReporter}.
*/
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
} String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
} if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
} AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} return null;
}

/**
* Parse the bean definition itself, without regard to name or aliases. May return
* <code>null</code> if problems occurred during the parsing of the bean definition.
*/
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
} try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
AbstractBeanDefinition bd = createBeanDefinition(className, parent); //返回GenericBeanDefinition 用于承载beanDefi parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //解析各种attr到bd
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); parseMetaElements(ele, bd);//<bean><meta..到bd
parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //<bean><lookup-method...到 bd
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());//<bean><replaced-method 到bd 动态替换bean里面的方法 parseConstructorArgElements(ele, bd);//<bean><constructor-arg... 到bd
parsePropertyElements(ele, bd); //<bean><property....到bd
parseQualifierElements(ele, bd); //<bean><qualifier 到bd bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele)); return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
} return null;
}

 

alians 也与bean类似

 

 
 
 
 

默认标签的解析过程(三)parseDefaultElement的更多相关文章

  1. Spring 系列教程之默认标签的解析

    Spring 系列教程之默认标签的解析 之前提到过 Spring 中的标签包括默认标签和自定义标签两种,而两种标签的用法以及解析方式存在着很大的不同,本章节重点带领读者详细分析默认标签的解析过程. 默 ...

  2. 《Spring源码深度解析》第三章 默认标签的解析

    上一章提到了,默认标签和自定义标签要分开解析.本章重点介绍默认标签的解析.在 DefaultBeanDefinitionDocumentReader 中: private void parseDefa ...

  3. Spring源码学习(2)——默认标签的解析

    上一篇随笔说到Spring对于默认标签和自定义标签的解析方法是不同的,这里详细看一下Spring对于默认标签的解析. private void parseDefaultElement(Element ...

  4. spring源码学习之默认标签的解析(一)

    继续spring源码的学习之路,现在越来越觉得这个真的很枯燥的,而且我觉得要是自己来看源码,真的看不下去,不是没有耐心,而是真的没有头绪,我觉得结合着书来看,还是很有必要的,最起码大致的流程是能够捋清 ...

  5. spring源码学习之默认标签的解析(二)

    这个是接着上一篇来写,主要是这章内容比较多,还是分开来写吧! 一.AbstractBeanDefinition属性介绍 XML中的所有的属性都可以在GenericBeanDefinition中找到对应 ...

  6. kafka 名词解释及原理解析过程(三)

    为什么要了解这些名词的解释呢?因为在学一个新的知识或者领域的时候,我们需要知道它所定义的概念和名词意思,因为只有这样我们才能理解和掌握这个新的知识点,才能更加系统的掌握这个技术. 一.名词解释 1.b ...

  7. jsp的运行内幕--Tomcat容器对自定义标签的解析过程

    http://blog.sina.com.cn/s/blog_4adc4b090101daqb.html

  8. spring源码深度解析— IOC 之 默认标签解析(上)

    概述 接前两篇文章  spring源码深度解析—Spring的整体架构和环境搭建  和  spring源码深度解析— IOC 之 容器的基本实现 本文主要研究Spring标签的解析,Spring的标签 ...

  9. Spring源码分析(七)bean标签的解析及注册

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇中提到过Spring中的标签包括默认标签和自定义标签两种,而两种 ...

随机推荐

  1. k8s系列文章第五篇(docker-compose)

    更多精彩内容,猛搓这里 目录 一.Docker Compose 1.前言 2.官方介绍 1.Compose 中有两个重要的概念 2.三步骤 3.Compose是Docker官方的开源项目,需要安装! ...

  2. At 、Crontabl定时任务

    之前笔者是在本地写的博客,然后用 windows 定时任务启动写的脚本上传到 Github 上,现在又遇到了 Linux 上的定时任务,项目还要用到 Quartz 定时任务框架 1. 一次性定时任务 ...

  3. ECShop 2.x/3.x SQL注入/任意代码执行漏洞

    poc地址:https://github.com/vulhub/vulhub/blob/master/ecshop/xianzhi-2017-02-82239600/README.zh-cn.md 生 ...

  4. 卷积的等变性(equivariant) / 不变性(invariant)

    不变性:输入x发生变换,但是F之后的输出不变 \(F(x)=F [\)transform\((x)]\) 池化:近似不变性,当图像发生微小变化,最大池化的输出不变,还是一个池化范围内的max 等变性: ...

  5. ASP.NET MVC部署网站到IIS,只列出网站目录

    解决办法: 1.重启IIS 打开CMD运行以下代码: ps:根据发布网站的的.NET Framework版本进入对应的目录 4.0版本  C:\Windows\Microsoft.NET\Framew ...

  6. noip模拟22[d·e·f]

    noip模拟22 solutions 哈哈哈,这次暴力打满直接190,其实不到哈哈哈,187.. 这次的题暴力极其好打,但是正解确实不简单... 打了好久才改完这个题,改完的时候爽暴了 这些一个字母的 ...

  7. 密码三次就会锁掉 while 循环

    while 只要给定的条件为真,C 语言中的 while 循环语句会重复执行一个目标语句 一般定义 //return_type function_name( parameter list ) //{ ...

  8. 字节跳动Android实习面试难吗,应该如何应对?

    字节跳动的面试难不难其实很难去非常准确的定义,但是能肯定的一点是,字节跳动的面试题都很有水平,真正考察了该岗位在以后工作中需要的能力. 大学学的Java后面又自学Android方向,跟着老师在实验室做 ...

  9. CentOS文件目录类语法

    目录 一.目录查看切换类 1. pwd 显示当前工作目录的绝对路径 2. ls 列出目录的内容 二.文件与目录创建删除类 1. mkdir 创建一个新目录 2. touch 创建空文件 3. rmdi ...

  10. 为什么npm install 经常失败

    Hello 您好,我是大粽子.深耕线上商城的攻城狮(程序员)一枚. 前言 这段时间真的是忙,最近能抽时间搞搞大家在自己环境中遇到的各种问题了,我呢就是见不得我的代码在你的电脑运行不起来的.就像姜子牙睡 ...