Spring解析及注册BeanDefinition

上一篇文章介绍了资源文件转为Document文件.
下面接着介绍doLoadBeanDefinitions中最核心的部分.如果说前面两篇文章都是介绍XML解析的准备阶段的话,那么registerBeanDefinitions()里面会进行真正的XML文件的解析.
把代码贴一遍

	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			Document doc = doLoadDocument(inputSource, resource);
			int count = registerBeanDefinitions(doc, resource);
			return count;
		}
		catch (Exception ex) {
			throw ex;
		}
	}

有时候我会把源码中的异常捕获或者日志等多余无关紧要的方法删掉.
进入registerBeanDefinitions方法:

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	// 这里实例化的是DefaultBeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		// 记录统计前BeanDefinition的加载个数
		int countBefore = getRegistry().getBeanDefinitionCount();
		// 加载及注册
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		// 返回本次加载的BeanDefinition个数
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		// doc.getDocumentElement()	是document的root
		// 以便根据root再进行操作
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}
	protected void doRegisterBeanDefinitions(Element root) {
		// 专门处理解析
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		// 处理profile属性
		if (this.delegate.isDefaultNamespace(root)) {
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					return;
				}
			}
		}
		// 解析前最后一次修改配置文件的地方,留给子类实现
		preProcessXml(root);
		// 解析处理
		parseBeanDefinitions(root, this.delegate);
		// 解析后处理,留给子类实现
		postProcessXml(root);

		this.delegate = parent;
	}

首先我们先来看一下PROFILE_ATTRIBUTE属性,其实平时我们在xml文件中使用profile属性并不是很常用.

<beans profile="dev">
	.....
</beans>
<beans profile="production">
	.....
</beans>

集成到Web环境中,在web.xml中加入以下代码:

<context-param>
	<param-name>Spring.profiles.active</param-name>
	<param-name>dev</param-name>
</context-param>

使用这个特性,就可以在配置文件中部署两套配置来适用于开发环境和生产环境.
代码中就是先获取beans节点是否定义了profile属性,如果定义了则需要到环境变量里去找,所以会先使用断言判断environment不能为空.因为profile可以通过一定的分隔符来定义多个,所以需要进行拆分,并且解析每个profile都是符合环境变量中所定义的.

解析并注册BeanDefinition
根据代码到parseBeanDefinitions(root, this.delegate)

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		// 根节点是不是默认的命名空间
		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)) {
						parseDefaultElement(ele, delegate);
					}
					// 否则使用自定义命名空间解析
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		// 节点不是默认的命名空间怎使用自定义命名空间进行解析
		else {
			delegate.parseCustomElement(root);
		}
	}

到这里最初的代码

Beanfactory bf = new XmlBeanFactory(new ClassPathResource("spring.xml"))

就已经告一段落了,但是上面讲到Spring对于两种命名空间的节点的解析还没有介绍,在后面的章节里会继续分析.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 6中的BeanDefinition是指在Spring容器中定义和配置的一个实例化对象的元数据。它描述了要创建的对象的属性、构造函数参数和其他配置信息。 BeanDefinition包含了以下重要的属性: 1. Bean的Class:指定要创建的对象的类。 2. Bean的作用域(Scope):指定对象的生命周期管理方式,包括Singleton、Prototype、Request、Session等。 3. Bean的依赖关系:指定对象之间的依赖关系,即其他Bean定义的引用。 4. Bean的初始化和销毁方法:指定对象初始化时执行的方法和销毁时执行的方法。 5. Bean的属性值和引用:指定对象的属性值,可以是基本类型值或其他Bean的引用。 6. Bean的构造函数参数:指定实例化对象时传递给构造函数的参数。 通过配置BeanDefinitionSpring容器能够根据这些元数据来创建和管理Bean实例。在容器启动时,会解析并根据BeanDefinition来实例化对象,并进行必要的依赖注入、初始化和销毁操作。每个BeanDefinition都代表了一个独立的对象定义,通过指定不同的属性值和配置,可以创建不同的对象实例。 BeanDefinition的配置可以使用XML、注解或Java Config等方式进行。使用Spring的IoC容器可以很方便地管理和配置大量的BeanDefinition,使得开发人员能够更加灵活和高效地控制对象的创建和管理。 总之,BeanDefinitionSpring框架用于描述和配置对象实例化的元数据,通过配置BeanDefinition,可以对对象的属性、依赖关系、作用域等进行管理和配置,从而实现灵活的对象创建和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值