Spring关于beanDefinition解析部分的源码解读

BeanDefinitionParserDelegate
这块内容是BeanDefinitionParserDelegate对bean标签属性的解析,下面对每一步详细解读

public AbstractBeanDefinition parseBeanDefinitionElement(
		Element ele, String beanName, @Nullable BeanDefinition containingBean) {

	this.parseState.push(new BeanEntry(beanName));

	String className = null;
	if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
		className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
	}
	String parent = null;
	if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
		parent = ele.getAttribute(PARENT_ATTRIBUTE);
	}

	try {

//1. 根据className 和 parent 创建用于属性承载的BeanDefinition

		AbstractBeanDefinition bd = createBeanDefinition(className, parent);

//2. 解析各种属性

		parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
		bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

//3. 解析子元素meta

		parseMetaElements(ele, bd);

//4. 解析子元素lookup-method

		parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

//5. 解析子元素replaced-method

		parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

//6. 解析子元素constructor-arg

		parseConstructorArgElements(ele, bd);

//7. 解析子元素property

		parsePropertyElements(ele, bd);

//8. 解析子元素qualifier

		parseQualifierElements(ele, bd);

		bd.setResource(this.readerContext.getResource());
		bd.setSource(extractSource(ele));

		return bd;
	... ...

接下来看第一部分 解析各种属性 结合代码看

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
			@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {

	if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {

// 1.0以后 没有singleton属性 已升级为scope属性

		error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
	}
	else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {

//scope作用域 通常是singleton 或 prototype

		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属性为true表示是抽象类 不要去实例化

	if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
	bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
	}

lazy-init 是否进行延迟初始化

	String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
	if (DEFAULT_VALUE.equals(lazyInit)) {
		lazyInit = this.defaults.getLazyInit();
	}
	bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

控制bean属性是否为“自动装配”。这是一个自动化过程,其中bean引用不需要在XML bean定义文件中显式编码,而是Spring容器计算出依赖项。有4种模式:1. no 没有自动装配 2.byName 按属性名称自动装配 3. byType 按属性类型自动装配 4. constructor 构造函数自动装配

	String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
	bd.setAutowireMode(getAutowireMode(autowire));

此bean依赖于初始化的bean的名称。 bean工厂将保证在这个bean之前初始化这些bean

	if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
		String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
		bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
	}

autowire-candidate 指示在查找匹配的候选项以满足另一个bean的自动装配要求时是否应该考虑此bean

	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));
	}

指定当多个候选者有资格自动装配单值依赖项时,应该优先考虑此bean

	if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
		bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
	}

init-method 设置bean属性后要调用的自定义初始化方法的名称

	if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
		String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
		bd.setInitMethodName(initMethodName);
	}
	else if (this.defaults.getInitMethod() != null) {
		bd.setInitMethodName(this.defaults.getInitMethod());
		bd.setEnforceInitMethod(false);
	}

destroy-method 要在bean工厂关闭时调用的自定义destroy方法的名称

	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);
	}

用于创建此对象的工厂方法的名称。如果采用参数,则使用constructor-arg元素指定工厂方法的参数

	if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
		bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
	}
	if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
		bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
	}

	return bd;
}

解析子元素meta

这里将meta的key value 构造BeanMetadataAttribute 当后面需要这些信息时可以通过beanDefinition的getAttribute(key)去获得

	public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
		NodeList nl = ele.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
				Element metaElement = (Element) node;
				String key = metaElement.getAttribute(KEY_ATTRIBUTE);
				String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
				BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
				attribute.setSource(extractSource(metaElement));
				attributeAccessor.addMetadataAttribute(attribute);
			}
		}
	}

解析子元素lookup-method

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值