Spring(三) BeanDefinition解析与注册

Posted by ZhouJ000 on August 27, 2018
最后更新于:2018-08-29

Spring(一) IOC核心类
Spring(二) Resource定位与载入
Spring(三) BeanDefinition解析与注册
Spring(四) 自定义标签解析
Spring(五) 其他初始化步骤
Spring(六) bean的加载01
Spring(七) bean的加载02
Spring(八) SpringBean的生命周期
Spring(九) IOC时序图
Spring(十) AOP 01
Spring(十一) AOP 02
Spring(十二) spring事务

回顾

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
	// 对beans处理,默认的namespace
	if (delegate.isDefaultNamespace(root)) {
		NodeList nl = root.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
				if (delegate.isDefaultNamespace(ele)) {
					// 对默认的元素标签处理,如<bean/> <alias/> <import/>
					parseDefaultElement(ele, delegate);
				}
				else {
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
	else {
		delegate.parseCustomElement(root);
	}
}

默认标签解析

分别对4种不同的默认标签做处理

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
	// a.import标签解析
	if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
		importBeanDefinitionResource(ele);
	}
	// b.alias标签解析
	else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
		processAliasRegistration(ele);
	}
	// c.bean标签解析
	else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
		processBeanDefinition(ele, delegate);
	}
	// d.beans标签解析
	else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
		// recurse递归
		doRegisterBeanDefinitions(ele);
	}
}

import标签解析

一般大的项目会分模块,会有不同的配置文件,可以使用import标签将不同配置文件导入到applicationContext.xml中

protected void importBeanDefinitionResource(Element ele) {
	//获取resource属性的路径
	String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
	if (!StringUtils.hasText(location)) {
		getReaderContext().error("Resource location must not be empty", ele);
		return;
	}

	// 解析系统属性  Resolve system properties: e.g. "${user.dir}"
	location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

	Set<Resource> actualResources = new LinkedHashSet<>(4);

	// 判定location是绝对URI还是相对URI  Discover whether the location is an absolute or relative URI
	boolean absoluteLocation = false;
	try {
		absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
	}
	catch (URISyntaxException ex) {
		// cannot convert to an URI, considering the location relative
		// unless it is the well-known Spring prefix "classpath*:"
	}

	// Absolute or relative?
	// 如果是绝对URI,直接根据地址加载相应的配置文件
	if (absoluteLocation) {
		try {
			// 开始执行上一篇(二)文章(2-b-4.)的AbstractBeanDefinitionReader.loadBeanDefinitions方法
			int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
			if (logger.isDebugEnabled()) {
				logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
			}
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error(
					"Failed to import bean definitions from URL location [" + location + "]", ele, ex);
		}
	}
	else {
		// No URL -> considering resource location as relative to the current file.
		// 如果是相对路径,根据相对地址计算出绝对路径
		try {
			int importCount;
			// Resource存在多个子实现类,如UrlResource,VfsResource,FileSystemResource等,
			// 而每个resource的createRelative的实现都不同,所以这里先使用子类的方法尝试解析
			Resource relativeResource = getReaderContext().getResource().createRelative(location);
			if (relativeResource.exists()) {
				importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
				actualResources.add(relativeResource);
			}
			else {
				// 如果解析不成功,则在上一篇(二)文章(2-b-4.)的
				// AbstractBeanDefinitionReader.loadBeanDefinitions里使用默认的解析器ResourcePatternResolver进行解析
				String baseLocation = getReaderContext().getResource().getURL().toString();
				importCount = getReaderContext().getReader().loadBeanDefinitions(
						StringUtils.applyRelativePath(baseLocation, location), actualResources);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
			}
		}
		catch (IOException ex) {
			getReaderContext().error("Failed to resolve current resource location", ele, ex);
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
					ele, ex);
		}
	}
	Resource[] actResArray = actualResources.toArray(new Resource[0]);
	// 进行监听器激活处理: 用户自扩展用,默认EmptyReaderEventListener.importProcessed是个空方法
	getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}

alias标签解析

不同组件可能会对同一个bean使用不同的别名,可以用alias标签指定,也可以直接在name属性中用’,’分隔指定

protected void processAliasRegistration(Element ele) {
	// 获取beanName
	String name = ele.getAttribute(NAME_ATTRIBUTE);
	// 获取alias
	String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
	boolean valid = true;
	if (!StringUtils.hasText(name)) {
		getReaderContext().error("Name must not be empty", ele);
		valid = false;
	}
	if (!StringUtils.hasText(alias)) {
		getReaderContext().error("Alias must not be empty", ele);
		valid = false;
	}
	if (valid) {
		try {
			// 注册alias: 详见 `bean标签解析-c-3.通过别名注册BeanDefinition`
			getReaderContext().getRegistry().registerAlias(name, alias);
		}
		catch (Exception ex) {
			getReaderContext().error("Failed to register alias '" + alias +
					"' for bean with name '" + name + "'", ele, ex);
		}
		// 注册后通知监听器做相应处理: 用户自扩展用,默认EmptyReaderEventListener.aliasRegistered是个空方法
		getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
	}
}

bean标签解析

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	// a.进行元素解析
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		// b.若存在默认标签的子节点下还有自定义属性,还需要再次对自定义标签进行解析
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// Register the final decorated instance.
			// c.对解析后的bdHolder进行注册
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// d.最后发出响应事件,通知相关的监听器  Send registration event.
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

a-1 . 委托给BeanDefinitionParserDelegate类进行元素解析,返回BeanDefinitionHolder

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
	// 解析id属性
	String id = ele.getAttribute(ID_ATTRIBUTE);
	// 解析name属性
	String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
	// 分割name属性
	List<String> 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.isDebugEnabled()) {
			logger.debug("No XML 'id' specified - using '" + beanName +
					"' as bean name and " + aliases + " as aliases");
		}
	}

	if (containingBean == null) {
		// 从Set<String> usedNames校验唯一性
		checkNameUniqueness(beanName, aliases, ele);
	}
	// -2:对标签其他属性的解析
	AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
	if (beanDefinition != null) {
		// 如果不存在beanName那么根据spring提供的命名规则为当前bean生成对应的beanName
		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.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);
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}

	return null;
}

a-2 . 对其他属性的解析

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 {
		// -3:创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
		AbstractBeanDefinition bd = createBeanDefinition(className, parent);
		// -4:硬编码解析默认bean的各种属性
		parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
		// 提取description
		bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
		// -5:解析元数据
		parseMetaElements(ele, bd);
		// -6:解析lookup-method属性
		parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
		// -6:解析replaced-method属性
		parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
		// -7:解析构造函数
		parseConstructorArgElements(ele, bd);
		// -8:解析property子元素
		parsePropertyElements(ele, bd);
		// -8:解析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;
}

a-3 . 创建用于承载属性的BeanDefinition GenericBeanDefinition是spring2.5以后提供的更好的注册bean definition类,它支持动态定义父依赖,是一站式的标准bean definition。
扩展资料:spring beans源码解读之–Bean的定义及包装

return BeanDefinitionReaderUtils.createBeanDefinition(
			parentName, className, this.readerContext.getBeanClassLoader());
	
public static AbstractBeanDefinition createBeanDefinition(
		@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {

	GenericBeanDefinition bd = new GenericBeanDefinition();
	bd.setParentName(parentName);
	if (className != null) {
		if (classLoader != null) {
			bd.setBeanClass(ClassUtils.forName(className, classLoader));
		}
		else {
			bd.setBeanClassName(className);
		}
	}
	return bd;
}	

a-4 . 解析各种属性

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
		@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
	// singleton属性过时了
	if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
		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.
		// 在嵌入beanDefinition情况下且没有单独指定scope,使用父类的属性
		bd.setScope(containingBean.getScope());
	}
	// 解析abstract属性
	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();	// 默认false
	}
	bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
	// 解析autowire属性
	String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
	bd.setAutowireMode(getAutowireMode(autowire));
	// 解析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();	// 默认null
		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);
		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;
}

a-5 . 解析子元素meta

public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
	// 获取当前节点所有子元素
	NodeList nl = ele.getChildNodes();
	for (int i = 0; i < nl.getLength(); i++) {
		Node node = nl.item(i);
		// 提取meta
		if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
			Element metaElement = (Element) node;
			String key = metaElement.getAttribute(KEY_ATTRIBUTE);
			String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
			// 使用key,value构造BeanMetadataAttribute
			BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
			attribute.setSource(extractSource(metaElement));
			// 记录信息
			attributeAccessor.addMetadataAttribute(attribute);
		}
	}
}

a-6 . 解析子元素lookup-method,解析replaced-method属性

public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
	NodeList nl = beanEle.getChildNodes();
	for (int i = 0; i < nl.getLength(); i++) {
		Node node = nl.item(i);
		if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
			Element ele = (Element) node;
			// 获取需要修饰的方法
			String methodName = ele.getAttribute(NAME_ATTRIBUTE);
			// 获取配置返回bean
			String beanRef = ele.getAttribute(BEAN_ELEMENT);
			LookupOverride override = new LookupOverride(methodName, beanRef);
			override.setSource(extractSource(ele));
			overrides.addOverride(override);
		}
	}
}

public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
	NodeList nl = beanEle.getChildNodes();
	for (int i = 0; i < nl.getLength(); i++) {
		Node node = nl.item(i);
		if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
			Element replacedMethodEle = (Element) node;
			// 获取要替换的旧方法
			String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
			// 获取对应新的替换方法
			String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
			ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
			// Look for arg-type match elements.
			List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
			for (Element argTypeEle : argTypeEles) {
				// 记录参数
				String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
				match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
				if (StringUtils.hasText(match)) {
					replaceOverride.addTypeIdentifier(match);
				}
			}
			replaceOverride.setSource(extractSource(replacedMethodEle));
			overrides.addOverride(replaceOverride);
		}
	}
}

无论是lookup还是replaced都是构造了一个MethodOverrie,并最终记录在了AbstractBeanDefinition中的methodOverrides属性中。
扩展资料:spring bean中子元素lookup-method和replaced-method

a-7 . 解析构造函数constructor-arg

public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
	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);
		}
	}
}
parseConstructorArgElement:
1.获取index属性、type属性、name属性
2.解析constructor-arg的子元素
	->a
3.使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
4.将type、name和source属性都封装在ConstructorArgumentValues.ValueHolder类型中
5.如果配置中指定了index属性
	添加到当前BeanDefinition的constructorArgumentValues的indexedArgumentValues属性中
5.如果没有指定index属性
	添加到当前BeanDefinition的constructorArgumentValues的genericArgumentValues属性中


a-1.略过description或者meta
a-2.提取constructor-arg上的ref和value属性,以便于根据规则验证正确性,其规则为在constructor-arg上不存在以下情况:
	1.同时既有ref属性又有value属性
	2.存在ref属性或者value属性,且有子元素
a-3.ref属性的处理:使用RuntimeBeanReference封装对应的ref名称
a-4.value属性的处理:使用TypedStringValue封装
a-5.子元素处理-> BeanDefinitionParserDelegate.parsePropertySubElement方法
	 -> 对自定义、ref、idref、value、null、array、list、set、map、props子元素的分别解析

a-8 . 解析property属性,解析qualifier属性

public void parsePropertyElement(Element ele, BeanDefinition bd) {
	// 获取配置元素中的name值
	String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
	if (!StringUtils.hasLength(propertyName)) {
		error("Tag 'property' must have a 'name' attribute", ele);
		return;
	}
	this.parseState.push(new PropertyEntry(propertyName));
	try {
		// 不允许多次对同一属性配置
		if (bd.getPropertyValues().contains(propertyName)) {
			error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
			return;
		}
		Object val = parsePropertyValue(ele, bd, propertyName);
		// 使用PropertyValue封装,最后记录在propertyValues中
		PropertyValue pv = new PropertyValue(propertyName, val);
		parseMetaElements(ele, pv);
		pv.setSource(extractSource(ele));
		bd.getPropertyValues().addPropertyValue(pv);
	}
	finally {
		this.parseState.pop();
	}
}

通过qualifier可以指定注入bean的名称,一般是通过注解配置,解析过程与property类似。


b.1 . 对于在默认标签下的属性,有可能是自定义属性,所以还需要再次对自定义标签解析

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

public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
		Element ele, BeanDefinitionHolder definitionHolder, @Nullable BeanDefinition containingBd) {

	BeanDefinitionHolder finalDefinition = definitionHolder;
	// Decorate based on custom attributes first.
	NamedNodeMap attributes = ele.getAttributes();
	// 遍历所有属性,查看是否有需要解析(装饰)的属性
	for (int i = 0; i < attributes.getLength(); i++) {
		Node node = attributes.item(i);
		finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
	}
	// Decorate based on custom nested elements.
	NodeList children = ele.getChildNodes();
	// 遍历所有子节点,查看是否有需要解析(装饰)的子元素
	for (int i = 0; i < children.getLength(); i++) {
		Node node = children.item(i);
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
		}
	}
	return finalDefinition;
}

b-2 . 对自定义标签或属性,通过寻找命名空间处理器来进一步解析(装饰)

public BeanDefinitionHolder decorateIfRequired(
		Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
	// 获取自定义标签的命名空间
	String namespaceUri = getNamespaceURI(node);
	// 对非默认标签进行修饰
	if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
		// 根据命名空间找到对应的处理器
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler != null) {
			// 委托给不同的命名空间处理器BeanDefinitionHolder进行具体的解析
			BeanDefinitionHolder decorated =
					handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
			if (decorated != null) {
				return decorated;
			}
		}
		else if (namespaceUri.startsWith("http://www.springframework.org/")) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
		}
		else {
			// A custom namespace, not to be handled by Spring - maybe "xml:...".
			if (logger.isDebugEnabled()) {
				logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
			}
		}
	}
	return originalDef;
}

c-1 . 委托给了BeanDefinitionReaderUtils对BeanDefinitionHolder进行注册

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

	// 使用beanName做唯一标识注册  Register bean definition under primary name.
	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);
		}
	}
}

c-2 . 通过beanName注册BeanDefinition

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");

	if (beanDefinition instanceof AbstractBeanDefinition) {
		try {
			// 注册前的最后一次校验,这里的校验不同于之前的XML文件校验
			// 主要是对于AbstractBeanDefinition属性中的methodOverrides校验
			// 校验methodOverrides是否与工厂方法或者methodOverrides对应的方法不存在
			// (hasMethodOverrides() && getFactoryMethodName() != null) / prepareMethodOverrides()
			((AbstractBeanDefinition) beanDefinition).validate();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Validation of bean definition failed", ex);
		}
	}
	// 是否有已注册的beanName
	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
	if (existingDefinition != null) {
		// 如果有对应的beanName已被注册,且配置里配置了不允许bean被覆盖,抛出异常
		if (!isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
					"': There is already [" + existingDefinition + "] bound.");
		}
		else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
			if (logger.isWarnEnabled()) {
				logger.warn("Overriding user-defined bean definition for bean '" + beanName +
						"' with a framework-generated bean definition: replacing [" +
						existingDefinition + "] with [" + beanDefinition + "]");
			}
		}
		else if (!beanDefinition.equals(existingDefinition)) {
			if (logger.isInfoEnabled()) {
				logger.info("Overriding bean definition for bean '" + beanName +
						"' with a different definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		else {
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding bean definition for bean '" + beanName +
						"' with an equivalent definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		this.beanDefinitionMap.put(beanName, beanDefinition);
	}
	else {
		// Check whether this factory's bean creation phase already started
		// i.e. whether any bean has been marked as created in the meantime
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			// beanDefinitionMap存在并发访问,需要同步更新
			synchronized (this.beanDefinitionMap) {
				this.beanDefinitionMap.put(beanName, beanDefinition);
				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				if (this.manualSingletonNames.contains(beanName)) {
					Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
					updatedSingletons.remove(beanName);
					this.manualSingletonNames = updatedSingletons;
				}
			}
		}
		else {
			// 依旧处于启动注册阶段,记录注册  Still in startup registration phase
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			this.manualSingletonNames.remove(beanName);
		}
		this.frozenBeanDefinitionNames = null;
	}

	if (existingDefinition != null || containsSingleton(beanName)) {
		// 为给定的bean重置所有BeanDefinition缓存
		resetBeanDefinition(beanName);
	}
}

c-3 . 通过别名注册BeanDefinition

public void registerAlias(String name, String alias) {
	Assert.hasText(name, "'name' must not be empty");
	Assert.hasText(alias, "'alias' must not be empty");
	synchronized (this.aliasMap) {
		// 如果alias与beanName相同,不记录alias,并删除对应的alias
		if (alias.equals(name)) {
			this.aliasMap.remove(alias);
			if (logger.isDebugEnabled()) {
				logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
			}
		}
		else {
			String registeredName = this.aliasMap.get(alias);
			if (registeredName != null) {
				if (registeredName.equals(name)) {
					// An existing alias - no need to re-register
					return;
				}
				// 如果不允许被覆盖,抛出异常
				if (!allowAliasOverriding()) {
					throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
							name + "': It is already registered for name '" + registeredName + "'.");
				}
				if (logger.isInfoEnabled()) {
					logger.info("Overriding alias '" + alias + "' definition for registered name '" +
							registeredName + "' with new target name '" + name + "'");
				}
			}
			// alias循环监察,A->B存在时,若再次出现A->C->B则抛出异常
			checkForAliasCircle(name, alias);
			// map记录
			this.aliasMap.put(alias, name);
			if (logger.isDebugEnabled()) {
				logger.debug("Alias definition '" + alias + "' registered for name '" + name + "'");
			}
		}
	}
}

d-1 . 通知监听器

this.eventListener.componentRegistered(componentDefinition);

EmptyReaderEventListener.componentRegistered()(ComponentDefinition componentDefinition){// no-op}

这里的实现只为扩展,当需要对注册BeanDefinition事件进行监听时,可以通过注册监听器的方式将处理逻辑写到监听器中。spring没有对此事件做任何逻辑

beans标签解析

返回上一篇文章(二)执行(2-b-10.)的DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法进行递归解析