二.解析BeanDefinition

解析Xml和获取Document的过程省略

当把Xml文件转换成Document对象后,接下来就可以提取和注册Bean了。

入口方法:

public int registerBeanDefinition(Document doc,Resource resource){

	BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
	//设置当前环境
	documentReader.setEnvironment(this.getEnvironment);
	//记录统计前BeanDefinition的加载个数
	int countBefore = getRegistry().getBeanDefinitionCount();
	//加载、注册Bean
	documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
	//记录本次加载的BeanDefinition个数
	return getRegistry().getBeanDefinitionCount() - countBefore;
}

Document是从Xml解析出来的Document对象。这个Docment对象是由BeanDefinitionDocumentReader来实现加载出来的,而这个只是个接口,其实现类是DefaultBeanDefinitionDocumentReader。进入到加载、注册Bean的方法以后,其实就是将Document对象中的root提取出来,在调用注册Bean的方法。

public void registerBeanDefinitions(Document doc,XmlReaderContext readerContext){
	this.readerContext = readerContext;
	//提取root
	Element root = doc.getDocumentElement();
	//使用root加载资源
	doRegisterBeanDefinitions(root);

}

doRegisterBeanDefinitions(root)才是真正加载Bean的入口方法。

protect void doRegisterBeanDefinitions(Element root){
	//处理profile属性---->在同一个项目中定义生产环境、上线环境等等,方便切换
	String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
	if(StringUtils.hasText(profileSpec)){
	//处理profile
		...
	}
	//专门解析Bean
	BeanDefinitionParserDelegate parent = this.delegate;
	this.delegate = createHelper(readerContext,root,parent);
	
	//解析前处理,留给子类实现---->模板方法模式
	preProcessXml(root);

	//根据node节点解析bean
	parseBeanDefinitions(root,this.delegate);


	//解析后处理,留给子类实现
	postProcessXml(root);
	
	this.delegate = parent;
}

1.Profile介绍

profile用于切换生产环境和开发环境(springboot中常用)

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

接下来就是设置当前的环境了

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

这样的话只解析dev所对应的beans标签
注:在springboot中直接使用yaml或者properties文件定义该属性即可

首先呢,spring会先尝试获取beans标签的profile属性,如果定义了会去当前Environment(前面已经把Environment设置到了documentReader中)中去寻找,如果当前环境是该profile定义的,才会去解析并注册该root,否则不会去解析bean而直接return。(即放弃了当前xml文件的解析)

root相当于代表每一个beans标签。注意是beans而不是bean

2.解析并且注册Bean

入口方法:

public void parseBeanDefinitions(Element root,BeanDefinitionParserDelegate delegate){

	/*
		1.处理beans
		2.处理bean
		对bean解析包括对自定义bean和anotation默认bean的解析 
	*/




}

下一节叙述bean的解析

猜你喜欢

转载自blog.csdn.net/xkshihaoren/article/details/87885876