解析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的解析