Spring之默认标签的解析(三) bean标签的解析及注册(2)—— BeanDefinition和其属性的解析

本文介绍了Spring中BeanDefinition的作用,它是配置文件元素在容器中的内部表示,包括RootBeanDefinition、ChildBeanDefinition和GenericBeanDefinition三种实现。BeanDefinition与XML标签属性一一对应,用于承载配置信息。Spring通过BeanDefinition将配置转换为内部表示并注册到BeanDefinitionRegistry。解析过程包括创建BeanDefinition实例和解析各种属性,如class、scope、lazy-init等。
摘要由CSDN通过智能技术生成

Spring之默认标签的解析(三) bean标签的解析及注册(2)BeanDefinition和其属性的解析

创建用于属性承载的BeanDefinition

  • createBeanDefinition
	protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
			throws ClassNotFoundException {
		return BeanDefinitionReaderUtils.createBeanDefinition(
				parentName, className, this.readerContext.getBeanClassLoader());
	}

  • createBeanDefinition
	 */
	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;
	}

上文中我们看了函数parseBeanDefinitionElement,其中调用了上述方法createBeanDefinition,目的就是为了创建BeanDefinition,而BeanDefinition的作用,我们分析下:

首先BeanDefinition是一个接口,在 Spring 中存在三种实现: RootBeanDefinition、ChildBeanDefinition 以及 GenericBeanDefinition 三 种实现均继承了 AbstractBeanDefinition ,其中 BeanDefinition 是配置文件元素标签在容器中的内部表示形式 。 元素标签拥有 class、 scope、 lazy-init等配置属性, BeanDefinition则提供了相应的 beanClass、 scope、 lazyInit 属性, BeanDefinition和中的属性是一一对应的。 其中 RootBeanDefinition是最常用的实现类,它对应一般性的元素标签,GenericBeanDefinition 是自 2.5 版本以后新加入的 bean 文件配置属性定义类,是一站式服务类。
在配置文件中可以定义父和子,父用 RootBeanDefinition 表示,而子 用 ChildBeanDefinition 表示,而没有父的就使用 RootBeanDefinition表示。 AbstractBeanDefinition 对两者共同的类信息进行抽象。Spring通过 BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些 BeanDefinition 注册到BeanDefinitionRegistry 中。Spring容器的 BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以 map 的形式保存,后续操作直接从 BeanDefinition­Registry 中读取配置信息 。

关系如图:
在这里插入图片描述

到此,我们就明白,要解析所有的属性,首先就是要创建用于承载属性的实例也就是创建beanDefinition类型的实例。

解析各种属性

创建完Bean的信息载体后,我们就可以逐步去完成bean信息的各种属性解析了,我们继续跟踪代码,首先就是parseBeanDefinitionAttributes方法

	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.
			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 (isDefaultValue(lazyInit)) {
			lazyInit = this.defaults.getLazyInit();
		}
		bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
		// 解析autowire属性
		String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
		bd.setAutowireMode(getAutowireMode(autowire));
		// 解析dependency-on属性
		if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
			String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
			bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
		}
		// 解析dependency-candidate属性
		String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
		if (isDefaultValue(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);
			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));
		}
		// 解析destroy-bean属性
		if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
			bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
		}

		return bd;
	}

到这里,spring完成了对bean各属性的解析。有部分属性,大概都没有怎么用过,等有时间我们一起探讨这些常用或非常用的属性。接下来我们还是先了解流程,预知结果如何,那下回分解吧…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值