默认命名空间

1:parseDefaultElement

从代码中可以了解到默认的命名空间的一节节点主要是4种,import,alias,bean,beans

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 1.对import标签的处理
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// 2.对alias标签的处理
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// 3.对bean标签的处理
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
// 4.对beans标签的处理
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
1.1:processBeanDefinition
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 1.进行节点定义解析, 经过这个方法后,bdHolder会包含一个BeanDefinition节点的所有属性,例如name、class、id
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 2.若存在默认标签的子节点下再有自定义属性,需要再次对自定义标签再进行解析,一般不使用
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 3.解析节点定义完成后,需要对解析后的bdHolder进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// 4.最后发出响应事件,通知相关的监听器,这个BeanDefinition已经加载完成了
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
1.1.1:parseBeanDefinitionElement
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
} public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
// 1.解析name和id属性
// 解析id属性
String id = ele.getAttribute(ID_ATTRIBUTE);
// 解析name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); // 分割name属性(通过逗号或分号)
// 例如:<bean name="demoService,demoServiceAlias" class=""/>,分割后aliases为
// [demoService,demoServiceAlias]
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
} // beanName默认使用id
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
// 如果id为空,并且aliases不为空,则取aliases的第一个元素作为beanName,其他的仍作为别名
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) {
// 检查beanName和aliases是否在同一个 <beans> 下已经存在
checkNameUniqueness(beanName, aliases, ele);
} // 2.进一步解析bean的其他所有属性并统一封装至GenericBeanDefinition类型实例中
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
// 3.如果bean定义存在,但是beanName为空,则用Spring默认的生成规则为当前bean生成beanName
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
// Spring提供的生成规则生成beanName,类似org.mybatis.spring.mapper.MapperScannerConfigurer#0
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)) {
// 如果Spring默认的生成规则生成的beanName为:类名加后缀,则将类名注册为别名
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);
// 4.将bean定义、beanName、bean别名数组封装成BeanDefinitionHolder
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} return null;
}

解析name,id属性, 其中name属性可以通过分隔符设置多个, 如果id存在, 那么使用id作为beanName, name属性分割后作为别名, 如果id不存在, 那么将name属性分割后第一个作为beanName, 剩下的全部作为别名

1.1.2parseBeanDefinitionElement

解析bean的其他属性并且统一封装至GenericBeanDefinition

解析calss,parent,然后利用这两个属性值, 创建AbstractBeanDefinition 类型的GenericBeanDefinition, 如果className,classLoader 都不为空的, 那么利用反射机制构建出BeanClass, 作为一个属性添加到GenericBeanDefinition

public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null;
// 1.解析class、parent属性
// 解析class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
} try {
String parent = null;
// 解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
// 2.创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent); // 3.解析bean的各种属性,这些属性定义在 AbstractBeanDefinition 中
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 提取description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); // 解析元数据子节点
parseMetaElements(ele, bd);
// 解析lookup-method子节点
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析replaced-method子节点
parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // 4.解析constructor-arg子节点
parseConstructorArgElements(ele, bd);
// 5.解析property子节点
parsePropertyElements(ele, bd);
// 解析qualifier子节点
parseQualifierElements(ele, 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;
}
1.1.2.1:parseBeanDefinitionAttributes
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
BeanDefinition containingBean, AbstractBeanDefinition bd) {
// 解析singleton属性
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
// singleton属性已经不支持, 如果使用了会直接抛出异常, 请使用scope属性代替
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// 解析scope属性
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
} // 解析abstract属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
} // 解析lazy-init属性, 默认为false
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); // 解析autowire属性
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire)); // 解析dependency-check属性
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.setDependencyCheck(getDependencyCheck(dependencyCheck)); // 解析depends-on属性
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
} // 解析autowire-candidate属性
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
} // 解析primary属性
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
} // 解析init-method属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.setInitMethodName(initMethodName);
}
}
else {
if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
} // 解析destroy-method属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
bd.setDestroyMethodName(destroyMethodName);
}
else {
if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
} // 解析factory-method属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
// 解析factory-bean属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
} return bd;
}

<bean>中的属性解析出来设置在GenericBeanDefinition

1.1.2.2:parseConstructorArgElements
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
// 拿到beanEle节点的所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
// 解析constructor-arg
parseConstructorArgElement((Element) node, bd);
}
}
}

获取bean节点中的所有子节点, 然后遍历解析所有是constructor-arg的节点

1.1.2.2.1:parseConstructorArgElement
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
// 1.提取基础属性index、type、name属性值
// 提取index属性
String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
// 提取type属性
String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
// 提取name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
if (StringUtils.hasLength(indexAttr)) {
try {
int index = Integer.parseInt(indexAttr);
if (index < 0) {
error("'index' cannot be lower than 0", ele);
}
else {
try {
// 2.index不为空的处理
this.parseState.push(new ConstructorArgumentEntry(index));
// 2.1解析ele节点对应的属性值
Object value = parsePropertyValue(ele, bd, null);
// 2.2使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
// 2.3将type属性封装到ConstructorArgumentValues.ValueHolder
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
// 2.4将name属性封装到ConstructorArgumentValues.ValueHolder
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
// 2.5判断index是否重复指定, 如果是则抛出异常
if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
error("Ambiguous constructor-arg entries for index " + index, ele);
}
else {
// 将index和valueHolder以key-value形式添加至当前BeanDefinition的constructorArgumentValues
// 的indexedArgumentValues属性中,(用于上面判断index是否重复指定)
bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
}
}
finally {
this.parseState.pop();
}
}
}
catch (NumberFormatException ex) {
error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
}
}
else {
try {
// 3.index为空的处理
this.parseState.push(new ConstructorArgumentEntry());
// 3.1解析ele节点对应的属性值
Object value = parsePropertyValue(ele, bd, null);
// 3.2使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
// 3.3将type属性封装到ConstructorArgumentValues.ValueHolder
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
// 3.4将name属性封装到ConstructorArgumentValues.ValueHolder
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
// 3.5将valueHolder添加至当前BeanDefinition的constructorArgumentValues的genericArgumentValues属性中
// 与上面的indexedArgumentValues类似,上面有index存为map,这边没index存为list
bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
}
finally {
this.parseState.pop();
}
}
}

首先拿到基础属性 index、type、name 的属性值。index不为空的处理, 先解析 ele 节点的值,每个 constructor-arg 节点必然有一个属性值,可能是通过 value 属性、ref 属性、list 属性等。判断index是否重复指定,如果是则抛出异常;如果不重复,则将 indexvalueHolderkey-value 形式添加至当前BeanDefinitionconstructorArgumentValuesindexedArgumentValues 属性中(用于前面判断index是否重复指定)。

1.1.2.3:parsePropertyElements
public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
// 拿到beanEle节点的所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
// 解析property节点
parsePropertyElement((Element) node, bd);
}
}
}

拿到 bean 节点的所有子节点,遍历解析所有是 property 节点的子节点, 并且bean 中的属性必须是类中要有 set 方法才可以使用,否则会抛出异常

1.1.2.3.1:parsePropertyElement
public void parsePropertyElement(Element ele, BeanDefinition bd) {
// 1.拿到name属性
String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
if (!StringUtils.hasLength(propertyName)) {
// name属性为必要属性,如果没有配置,则抛出异常
error("Tag 'property' must have a 'name' attribute", ele);
return;
}
this.parseState.push(new PropertyEntry(propertyName));
try {
// 2.校验在相同bean节点下,是否存在相同的name属性,如果存在则抛出异常
if (bd.getPropertyValues().contains(propertyName)) {
error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
return;
}
// 3.解析属性值
Object val = parsePropertyValue(ele, bd, propertyName);
// 4.将解析的属性值和属性name封装成PropertyValue
PropertyValue pv = new PropertyValue(propertyName, val);
// 5.解析meta节点
parseMetaElements(ele, pv);
pv.setSource(extractSource(ele));
// 6.将解析出来的PropertyValue,添加到BeanDefinition的propertyValues属性中(上面的重复校验用到)
bd.getPropertyValues().addPropertyValue(pv);
}
finally {
this.parseState.pop();
}
}
1.1.2:registerBeanDefinition
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException { // Register bean definition under primary name.
// 1.拿到beanName
String beanName = definitionHolder.getBeanName();
// 2.注册beanName、BeanDefinition到缓存中(核心逻辑),实现类为; DefaultListableBeanFactory
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any.
// 注册bean名称的别名(如果有的话)
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
// 3.注册bean的beanName和对应的别名映射到缓存中(缓存:aliasMap)
registry.registerAlias(beanName, alias);
}
}
}
1.1.2.1:registerBeanDefinition
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 1.beanName和beanDefinition为空校验
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// 注册前的最后校验
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
} BeanDefinition oldBeanDefinition; // 首先根据beanName从beanDefinitionMap缓存中尝试获取
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
// 2.beanName存在于缓存中
if (!isAllowBeanDefinitionOverriding()) {
// 如果不允许相同beanName重新注册,则直接抛出异常, 默认为true
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
} else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
} else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存(以供后续创建bean时使用)
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
// 3.beanName不存在于缓存中
if (hasBeanCreationStarted()) {
// 3.1 bean创建阶段已经开始
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将本次传进来的beanName 加入beanDefinitionNames缓存
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 将beanName从manualSingletonNames缓存移除
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
// 3.2 bean创建阶段还未开始
// Still in startup registration phase
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将本次传进来的beanName 加入beanDefinitionNames缓存
this.beanDefinitionNames.add(beanName);
// 将beanName从manualSingletonNames缓存移除
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
} // 4.如果存在相同beanName的BeanDefinition,并且beanName已经存在单例对象,则将该beanName对应的缓存信息、单例对象清除,
// 因为这些对象都是通过oldBeanDefinition创建出来的,需要被覆盖掉的,
// 我们需要用新的BeanDefinition(也就是本次传进来的beanDefinition)来创建这些缓存和单例对象
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
1.1.2.2: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");
// 1.如果别名和beanName相同,则不算别名,从aliasMap缓存中移除
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
// 2.如果别名已经注册过,直接返回
return;
}
// 3.如果存在相同的别名,并且不允许别名覆盖,则抛出异常
if (!allowAliasOverriding()) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
// 4.检查name和alias是否存在循环引用。例如A的别名为B,B的别名为A
checkForAliasCircle(name, alias);
// 5.将别名和beanName的映射放到aliasMap缓存中
this.aliasMap.put(alias, name);
}
}

总结

我们可以重新梳理一下思路,我们首先将 xml 中的 bean 配置信息进行了解析,并构建了 AbstractBeanDefinitionGenericBeanDefinition) 对象来存放所有解析出来的属性。然后,我们将 AbstractBeanDefinitionbeanNamealiasesArray 构建成 BeanDefinitionHolder 对象并返回。最后,我们通过 BeanDefinitionHolderBeanDefinitionbeanName 注册到 BeanFactory 中,也就是存放到缓存中。

执行完 parseDefaultElement 方法,我们得到了两个重要的缓存:beanDefinitionNames 缓存。beanDefinitionMap 缓存。

最新文章

  1. POJ 1308
  2. eclipse文本编码格式修改为UTF-8 (转)
  3. Windows Maven package时报错问题的解决
  4. DockerFile 参数详解
  5. Webform(分页、组合查询)
  6. Codeforce Round #222 Div2
  7. delphi 查找对话框
  8. Spring MVC一个方法适用多种调用方式
  9. python学习笔记之十:文件和素材
  10. Eclipse rap 富客户端开发总结(2):rap项目目前的进度和存在的问题
  11. Django学习日记06_视图_URLconf、View
  12. python-封装方法用于读取excel
  13. C#-继承(十一)
  14. CodeForces 570D - Tree Requests - [DFS序+二分]
  15. 将n的k位s置1
  16. python-django rest framework框架之序列化
  17. oracle C# 访问
  18. 每天学一点easyui①
  19. 计算机网络【3】—— IP地址分类与子网划分
  20. macOS安装MongoDB

热门文章

  1. net core 依赖注入DI
  2. Reverse for &#39;blog_detail.html&#39; not found.解决方法
  3. mysql 百万计数据导入--Load data infile
  4. Mysql优化工具
  5. 查看git的用户名和密码
  6. Python的100个小技巧
  7. 【Frida】Java反射调用
  8. D. Triangle Coloring
  9. postgresql数据库插入和读取图片
  10. elementUI中table组件前端自己实现序号排序