Spring源码分析-IOC之BeanDefinitionHolder

BeanDefinitionHolder顾名思义就是对BeanDefinition的持有,同时持有的包括BeanDefinition的名称和别名,BeanDefinition我们在前面的文章已经介绍过Spring源码分析-IOC之BeanDefinition,BeanDefinitionHolder同时实现了BeanMetadataElement,BeanMetadataElement我们在前面也已经介绍过Spring源码分析-IOC之BeanMetadataElement,有兴趣的同学可以看下,下面我们先看下BeanDefinitionHolder的源码:

//实现了BeanMetadataElement接口
public class BeanDefinitionHolder implements BeanMetadataElement {
    
    //持有BeanDefinition 
	private final BeanDefinition beanDefinition;
    //BeanDefinition的名称
	private final String beanName;
    //BeanDefinition的别名
    //Nullable注解表示该属性可以为空
	@Nullable
	private final String[] aliases;


	//根据bean的名称和beanDefinition初始化BeanDefinitionHolder
	public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
        //此次实际是调用的另外一个构造方法
		this(beanDefinition, beanName, null);
	}

	//根据bean的名称和beanDefinition,别名aliases初始化BeanDefinitionHolder
    //别名aliases可以为空
	public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) {
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
		Assert.notNull(beanName, "Bean name must not be null");
		this.beanDefinition = beanDefinition;
		this.beanName = beanName;
		this.aliases = aliases;
	}

	//根据指定的BeanDefinitionHolder 复制一个新的BeanDefinitionHolder 
    //此处不是深克隆
	public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) {
		Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null");
		this.beanDefinition = beanDefinitionHolder.getBeanDefinition();
		this.beanName = beanDefinitionHolder.getBeanName();
		this.aliases = beanDefinitionHolder.getAliases();
	}


	//获取BeanDefinition
	public BeanDefinition getBeanDefinition() {
		return this.beanDefinition;
	}

	//获取bean的名称
	public String getBeanName() {
		return this.beanName;
	}

	//获取别名
	@Nullable
	public String[] getAliases() {
		return this.aliases;
	}

	//获取beanDefinition的源对象,实现了BeanMetadataElement
	@Override
	@Nullable
	public Object getSource() {
		return this.beanDefinition.getSource();
	}

	//判断指定的名称与beanName或者别名身份匹配
	public boolean matchesName(@Nullable String candidateName) {
		return (candidateName != null && (candidateName.equals(this.beanName) ||
				candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) ||
				ObjectUtils.containsElement(this.aliases, candidateName)));
	}


	//返回一个描述包括bean的名称和所有的别名
	public String getShortDescription() {
		StringBuilder sb = new StringBuilder();
		sb.append("Bean definition with name '").append(this.beanName).append("'");
		if (this.aliases != null) {
			sb.append(" and aliases [").append(StringUtils.arrayToCommaDelimitedString(this.aliases)).append("]");
		}
		return sb.toString();
	}

	//返回一个长描述包括名称,别名已经beanDefinition的内容
	public String getLongDescription() {
		StringBuilder sb = new StringBuilder(getShortDescription());
		sb.append(": ").append(this.beanDefinition);
		return sb.toString();
	}

	//重写toString方法
	@Override
	public String toString() {
		return getLongDescription();
	}

    //重写equals方法
	@Override
	public boolean equals(Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof BeanDefinitionHolder)) {
			return false;
		}
		BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other;
		return this.beanDefinition.equals(otherHolder.beanDefinition) &&
				this.beanName.equals(otherHolder.beanName) &&
				ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases);
	}
    //重写hashCode方法
	@Override
	public int hashCode() {
		int hashCode = this.beanDefinition.hashCode();
		hashCode = 29 * hashCode + this.beanName.hashCode();
		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases);
		return hashCode;
	}

}

下面我们继续看BeanDefinitionHolder在spring中的应用,DefaultBeanDefinitionDocumentReader中在解析默认的标签bean元素的时候 :

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)) {
            //此处解析bean元素
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

接下来processBeanDefinition方法:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	//根据bean元素创建BeanDefinitionHolder 
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			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));
		}
	}

继续往下看BeanDefinitionParserDelegate中的parseBeanDefinitionElement:

	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
		return parseBeanDefinitionElement(ele, null);
	}

    
	@Nullable
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List aliases = new ArrayList<>();
		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.isTraceEnabled()) {
				logger.trace("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
        //解析bean元素的属性,创建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);
						// 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.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对象
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}

 以上方法实际上就是解析bean元素,创建beanDefinition,然后将beanDefinition,beanName,aliases创建为BeanDefinitionHolder,我们继续回到processBeanDefinition方法中:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 根据BeanDefinitionHolder 注册beanDefinition
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			//此处根据BeanDefinitionHolder 创建一个BeanComponentDefinition
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

我们继续看下BeanDefinitionReaderUtils.registerBeanDefinition的方法:

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// 就是根据BeanDefinitionHolder 的属性注册
        //注册的具体内容细节我们将会在后面将
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

以上就是BeanDefinitionHolder 在spring的主要功能。

小结:我们在开发中也可以借鉴BeanDefinitionHolder 这种方式,更好的封装我们的数据。

 

你可能感兴趣的:(spring,spring)