加载xml文件中的bean(二)
前言
此处声明下,个人的学习笔记,并不是很全,有些点可能不会太深入。
上一篇源码分析到了,解析xml里面的元素、标签。
// 解析默认命名空间,元素的类型
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 默认解析 4种ele
// 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);
}
// beans,递归调用解析
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
这里面bean的解析是最复杂的,包含了各种元素,默认定义的许多属性(attribute)
下面主要是分析 解析bean
的processBeanDefinition
方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析 BeanDefinition 元素得到 holder
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 装饰 holder(主要是对节点下面的自定义属性进行解析)
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 注册 被装饰后的 实例
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));
}
}
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 得到 id 属性
String id = ele.getAttribute(ID_ATTRIBUTE);
// 得到 name 属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<>();
// ,; 逗号 分号 空格 3个符号,对名字进行分割
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
// id作为beanName
String beanName = id;
// 如果beanName (id)没有,且别名列表不为空,就取别名列表的第一个
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isTraceEnabled()) {
logger.trace("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
// containingBean 为空,则检查名字是否有重复,beaName 和 别名列表
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 验证通过,解析元素
// 根据ele元素里面的属性,创建 beanDefinition
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);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("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);
// 返回 BeanDefinitionHolder
// 里面封装了 beanDefinition、beanName、aliasesArray 3个属性
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
// 此处就是根据ele元素 将xml里面定义的一个bean 转换成 系统识别的 beanDefinition
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
// 解析class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
// 解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建可以承载属性的 AbstractBeanDefinition (BeanDefinition)对象
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 硬编码解析bean的各种属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// Description 元素
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 元数据
parseMetaElements(ele, bd);
// lookup方法
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// replace方法
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 构造器
parseConstructorArgElements(ele, bd);
// property子元素
parsePropertyElements(ele, bd);
// qualifier子元素
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch
// ...省略catch部分
finally {
this.parseState.pop();
}
return null;
}
上面的源码是对bean节点,默认属性的解析、设置,并返回 BeanDefinitionHolder 对象。
registerBeanDefinition
这个方法是将 beanDefinition对象注册到 BeanDefinitionRegistry 中。BeanDefinitionRegistry 就类似内存数据库一样,key, value 键值对的形式来保存 beanName
对应的 BeanDefinition