默认命名空间

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 缓存。

解析bean封装成BeanDefinition的更多相关文章

  1. 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程

    原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...

  2. XML解析之sax解析案例(二)使用sax解析把 xml文档封装成对象

    Demo1类: import java.io.File; import java.util.List; import javax.xml.parsers.SAXParser; import javax ...

  3. SpringMVC 中,当前台传入多个参数时,可将参数封装成一个bean类

    在实际业务场景中,当前台通过 url 向后台传送多个参数时,可以将参数封装成一个bean类,在bean类中对各个参数进行非空,默认值等的设置. 前台 url ,想后台传送两个参数,userName 和 ...

  4. Spring源码解析(三)BeanDefinition的载入、解析和注册

    通过上一篇源码的分析已经完成了BeanDefinition资源文件的定位,本篇继续分析BeanDefinition资源文件的载入和解析. AbstractBeanDefinitionReader的lo ...

  5. Spring源码解析(二)BeanDefinition的Resource定位

    IOC容器的初始化过程主要包括BeanDefinition的Resource定位.载入和注册.在实际项目中我们基本上操作的都是ApplicationContex的实现,我们比较熟悉的ClassPath ...

  6. 微信开发03----------XML解析与封装

    3.1 解析微信发来的请求  微信服务器发来的请求消息都被封装在request对象中,可以从request对象中将请求参数取出来.通常是用request的getParament()方法获取请求中的参数 ...

  7. 将HTML5封装成android应用APK文件的几种方法(转)

    作为下一代的网页语言,HTML5拥有很多让人期待已久的新特性.HTML5的优势之一在于能够实现跨平台游戏编码移植,现在已经有很多公司在移动 设备上使用HTML5技术.随着HTML5跨平台支持的不断增强 ...

  8. hibernate将本地SQL查询结果封装成对象

    hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...

  9. 为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?

    既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的 ...

  10. 【Spring】BeanFactory解析bean详解

    在该文中来讲讲Spring框架中BeanFactory解析bean的过程,该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看,先来看一个在Spring中一个基本的bean定义与使用. pac ...

随机推荐

  1. Vue 超长列表渲染性能优化

    参考:https://juejin.cn/post/6979865534166728711#heading-3 组件懒加载参考:https://github.com/xunleif2e/vue-laz ...

  2. 【补题】The 2022 SDUT Summer Trials

    比赛链接 The 2022 SDUT Summer Trials A. Ginger's number 样例恶臭(恼) 签到题 简单分解因数就会发现要求的就是\(gcd\),直接算即可,时间复杂度\( ...

  3. maven发布到本地仓库

    <distributionManagement> <repository> <id>localRepository</id> <url>fi ...

  4. Head_First_Python(中文版)值得花时间读的一本书

    Head_First_Python(中文版)书籍免费下载 提取码:u6z5 内容简介  · · · · · · 你想过可以通过一本书就学会Python吗?<Head First Python(中 ...

  5. Appium元素选择 滑动 通知栏

    一.根据ID  包名可省略 1.元素的resource id属性 2.唯一标志该元素的值 3.一般最优先根据它来定位 driver.find_element_by_id('io.manong.deve ...

  6. python ddt file_data

    # -*- coding: utf-8 -*-"""------------------------------------------------- File Name ...

  7. 杭电oj 偶数求和

    Problem Description 有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值 ...

  8. vue指令入门

    1.  vue属性.事件.内容绑定 1 <div id="dv"> 2 <!-- v-cloak能够解决表达式闪烁问题 3 (当网速较慢时,会先出现{{msg}} ...

  9. Unity3D中实现按资源名称自动化命名打包AssetBundle

    首先把模型变成预制体 一般当需要打包成AssetBundle的资源不多时,可以自己通过AssetLabels窗口手动命名,然后再打包,但是当需要打包的资源过多时,一个一个的去手动编辑就特别的麻烦,因此 ...

  10. pip设置镜像

    国内镜像网站 镜像站名 网址 阿里云开源镜像站 http://mirrors.aliyun.com/ 网易开源镜像站 http://mirrors.163.com/ 搜狐开源镜像 http://mir ...