Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作
写在前面
上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读取配置文件,将其经过编码并经过系列处理后,交给了同类中的doLoadBeanDefinitions()方法,这次就直接进入这个方法,来看看Spring到底是如何创建BeanDefinition的。
1.2 BeanDefinition的创建 - 创建BeanDefinition前的最终准备
首先进入XmlBeanDefinitionReader.doLoadBeanDefinitions(InputSource inputSource, Resource resource)方法

方法很简单
- 创建XML文件的Document
- 根据Doucment和InputSource加载BeanDefinition
Doucument对象是W3C定义的XML格式的规范,它的创建我不是很感兴趣,这里就不再讨论,如果有兴趣大家可以自行百度,研究一下。
而我们期待的重点被再次委托,进入registerBeanDefinitions(Document doc,Resource resource)方法。

方法内部根据资源文件创建了一个XmlReaderContext后(不在我的关心范围内,跳过),被再次委托给BeanDefinitionDocumentReader接口中的同名方法,继续跟进。

从Document获取Element后,看到下面的方法名就知道接下来我们要进入真正的Bean元素解析的阶段了。
1.3 BeanDefinition的创建 - 解析BeanDefinition
protected void doRegisterBeanDefinitions(Element root) {
//todo flash 不太懂这两个的变换是什么意思,以后有时间可以仔细研究一下
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)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
// 开始解析
// 解析前,交给子类自定义实现
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
// 解析后,交给子类自定义实现
postProcessXml(root);
this.delegate = parent;
}
函数首先是处理profile,(关于这部分详尽的内容推荐这篇文章.)如果找不到对应的profile会直接跳过注册,结束方法。
preProcessXml()和postProcessXml()两个方法则是Spring留给外部拓展的方法,在Spring中与他们类似的方法有很多,我习惯性把它称为'前处理器'和'后处理器'。
而'前处理器'和'后处理器'中间的这个方法就是Bean解析的方法了,进入此方法。
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);
}
}
Spring中的标签分为两种,一种是默认的(Spring官方的)
<bean id="student" class="com.flash.springtest.dto.Student"/>
另一种则是我们自定义的
<!-- 看不懂就对了,所以是'自定义'标签 -->
<flash:stuednt key:com.flash.springtest.dto.Student>
如上,关于自定义标签的更多内容可以查看此篇文章,后续在解析自定义标签的环节中看心情要不要自己搞一搞。
这篇文章就先到这里,下篇将正式开始解析Spring的默认标签。
Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作的更多相关文章
- Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路
写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 ...
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
- Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md
写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...
- Spring源码学习之BeanFactory体系结构
一.BeanFactory BeanFactory是Spring IOC容器的鼻祖,是IOC容器的基础接口,所有的容器都是从它这里继承实现而来.可见其地位.BeanFactory提供了最基本的IOC容 ...
- spring源码学习五 - xml格式配置,如何解析
spring在注入bean的时候,可以通过bean.xml来配置,在xml文件中配置bean的属性,然后spring在refresh的时候,会去解析xml配置文件,这篇笔记,主要来记录.xml配置文件 ...
- Spring源码学习(2)——默认标签的解析
上一篇随笔说到Spring对于默认标签和自定义标签的解析方法是不同的,这里详细看一下Spring对于默认标签的解析. private void parseDefaultElement(Element ...
- Spring源码学习
Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...
- spring源码学习之路---IOC初探(二)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...
随机推荐
- Java位运算原理及使用讲解
前言日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法.举个例子,翻转操作比较常见,比如初始值为1,操作一次变为0,再操作一次变为1.可能的做法是使用三木运算符,判断原始值 ...
- hyperledger fabric部署总结
之前在有道云笔记上分享过,但想想还是搬到这里来吧,以后统一方便整理自己的知识进入正题.... 之前在调研 hyperledger fabric,其实部署说明官网都有,只是东西都是国外的照着操作也会遇到 ...
- MySQL5.7开启独立表空间参数innodb_file_per_table【原创】
今天在线上某个系统发现MySQL数据库使用的是共享表空间,想修改为独立表空间,操作如下: #因为是主从结构,在从库修改测试,先关闭binlog SET SQL_LOG_BIN=; show varia ...
- php中trait的使用
1.php中的trait是啥? 看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait是一种代 ...
- HTTP协议详解(三)
接着第二篇继续学习... 6 HTTP的几个重要概念 6.1连接:Connection 一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间. 在http1,request和reponse头中都 ...
- asp.net core 学习资料整理
net上海俱乐部 白手套大神分享 广州一位大佬总结的系列文章 https://www.cnblogs.com/viter/p/10474091.html 汪宇杰 http://edi.wan ...
- 定时-thinkphp
链接:https://pan.baidu.com/s/1wHayb9fYOiiMB3Scms0iRQ 提取码:51ex 复制这段内容后打开百度网盘手机App,操作更方便哦
- 网络流24题——骑士共存问题 luogu 3355
题目描述:这里 从这里开始,我们涉及到了一个新的问题:最小割问题 首先给出一些定义(本人根据定义自己口胡的): 一个流网络中的一个割是一个边集,使得割掉这些边集后源点与汇点不连通 而最小割问题就是一个 ...
- java获取application.properties和application.yml配置文件信息
public static void main(String[] args) { String result=getProjectConfig("max-file-size"); ...
- RPA 介绍
一 术语表 机器人流程自动化(RPA):在数字系统中模拟和集成人类行为以优化业务流程的软件机器人.RPA自动化捕获数据.运行应用程序.触发响应并与其他系统通信以执行各种任务. RPA路线图(RPA r ...