【spring源码系列】之【xml解析】
1. 读源码的方法
java程序员都知道读源码的重要性,尤其是spring的源码,代码设计不仅优雅,而且功能越来越强大,几乎可以与很多开源框架整合,让应用更易于专注业务领域开发。但是能把spring的源码吃透,不仅需要花费大量时间与精力,更需要需要掌握一些方法。下面结合自己读源码与走过的一些弯路,结合网上知名博客专家的建议,整理出以下要点,与读者共勉。
1.1 重视官方英文文档
spring的官方文档写的非常全面,基本可以认为是spring源码思想的一手来源,上面有很多例子不仅帮助读者如何应用,更能帮助我们了解其背后的思想,官方也用大量描述性的文字进行了相关思想的解读,让读者从一个总览上看大致了解spring的核心功能与特性。截止到目前,官方的最新版本是5.3.6,地址如下:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core。
1.2 写示例程序debug源码
通过简单的示例程序,找到源码的入口,通过debug而非仅仅看静态的源码,只有看到真实跑起来的程序以及运行时的值时,心里才大致清楚源码做了哪些事情。
1.3 抓大放小
抓住源码主要流程,而非陷入细节,如果一开始就抠细节,不仅会打消看源码的积极性,也理不清主要流程,最后只能半途而废。只有主流程非常熟悉的情况下,并有时间精力,有兴趣可以深究一些自己感兴趣的细节。
1.4 写源码注释、画流程图
源码的一些重要方法与主要流程可以通过写注释、画流程图来加深理解。
1.5 思考背后的设计思想
源码之所以经典,是因为设计思想优秀,spring的源码在设计模式的灵活应用、类的抽象与封装、框架的可扩展性都做到了极致,可以把该思想以及实践应用到自己的项目设计里面。
1.6 螺旋式学习
任何知识都是循序渐进,源码学习更是如此,因为源码很容易让人半途而废,只有通过刻意重复来逐步提升,每一次都不求甚解,能搞懂多少就搞懂多少,但是每一次都比上一次的理解提升一点,也可参考优质博客系列对比学习,最终将源码的精髓吃透。
2. xml文件解析
2.1 流程概览
上图描述了xml的解析的主要流程,大致分为三个步骤:
step1: 创建BeanFactory
对象;
step2: 解析xml标签,默认标签如bean
、import
,自定义标签<context:component-scan base-package=xxx>
,把标签封装成BeanDefinition
对象;
step3: 最后通过注册机BeanDefinitionRegistry
注册到BeanFactory
的实现类DefaultListableBeanFactory
。
2.2 源码分析
AbstractApplicationContext
类中最重要的方法refresh()
,里面调用很多方法,本文先重点看xml解析相关的方法。
进入obtainFreshBeanFactory()
方法,到refreshBeanFactory()
,该方法是个抽象方法,由具体子类实现。
子类AbstractRefreshableApplicationContext
实现refreshBeanFactory()
方法;
上面方法主要做了两件事,一是创建beanFactory
,二是beanFactory
作为参数传入,并负责装载BeanDefinition对象。接下来进入loadBeanDefinitions(beanFactory)
方法,该方法是个抽象方法,交给子类AbstractXmlApplicationContext
去实现,子类方法如下。
上述方法创建xml解析器XmlBeanDefinitionReader
,并交由解析器完成BeanDefinitions
的装载。再次进入AbstractXmlApplicationContext
类的loadBeanDefinitions
方法。
再次进入xml解析器的loadBeanDefinitions
方法,
进入上述的loadBeanDefinitions(resources)
方法;
上述方法一是封装Document
文件对象,二是用Document
对象去注册BeanDefinitions
,随后进入registerBeanDefinitions
方法;
该方法创建BeanDefinitionDocumentReader
对象,并委托其解析document,进入registerBeanDefinitions
方法。
上述方法主要完成默认标签解析,与自定义标签解析,默认标签如同import
、alias
、bean
、beans
,自定义标签比如<aop:aspectj-autoproxy />
,默认标签重点分析bean
标签的解析;
上述方法主要是bean
标签的解析,最后对BeanDefinition
对象进行缓存注册,先分析解析;
再分析注册BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())
,进入该方法,最后会进入DefaultListableBeanFactory
类,
最终看出所谓的注册到BeanFactory
的容器中的类,无非就是一个定义了ConcurrentHashMap
类型的beanDefinitionMap
。
自定义标签解析BeanDefinitionParserDelegate
类,执行parseCustomElement
方法;
上述过程主要完成以下步骤:
step1
:获取namespaceURI;
step2
:解析namespaceURI对应的handler类;
step3
:执行handler方法解析。
其中step2又分为几个步骤,代码进入如下方法
上述解析namespaceURI对应的handler类,对应步骤又课分为如下几步,
step1
:从spring.handler里面获取映射关系;
step2
:根据namespaceURI从映射关系map中获取对应的处理类handler;
step3
:通过反射获取handler对象,并执行init方法,完成自定义标签注册;
3. 总结
本文主要分析了xml标签的解析,主要步骤与流程图上述代码分析与时序图,通过调试可以清晰观察到解析过程,后续将通过示例分析beanDefinition
类的相关属性。
__EOF__

本文链接:https://www.cnblogs.com/father-of-little-pig/p/14645209.html
关于博主:不要为了技术而技术,总结分享技术,感恩点滴生活!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY