上一小节
庖丁解牛剖析 Spring 源码·acceptsProfiles()
承上启下
至此,关于 Spring 容器基本实现部分的源码已分析完毕,在此将之前的章节进行串联。
执行流程·准备工作
Spring 是什么?为什么会存在?有什么用途?借鉴唐僧的哲学三问,我们认识了Spring。
Spring 学习环境准备,工欲善其事必先利其器 环境搭建以及常用工具推荐。
Spring 源码分析 DEMO 示例 万事开头难,脚踏实地,先创建一个 DEMO。
执行流程·资源封装
使用 ClassPathResource 对存放 src/main/resource 目录的 spring.xml 文件进行资源封装。
执行流程·实例化 XmlBeanFactory 及其父类
ClassPathResource 作为 XmlBeanFactory 构造方法 的参数,在 实例化 new XmlBeanFactory 调用构造方法时 通过 super() 其父类
DefaultListableBeanFactory 构造方法,进而调用
DefaultListableBeanFactory 的父类
AbstractAutowireCapableBeanFactory 构造方法,进而调用
AbstractAutowireCapableBeanFactory 的父类 AbstractBeanFactory构造方法。
在
AbstractAutowireCapableBeanFactory 构造方法 中在成员属性
ignoredDependencyInterfaces 添加了 Aware 接口的三个子类,并分析为何在属性自动注入时需要忽略 Aware。
执行流程·实例化 BeanDefinitionReader 及其父类
实例化父类的构造方法结束后,回到 XmlBeanFactory 构造方法,首先实例化成员属性 XmlBeanDefinitionReader 构造方法,super() 实例化 XmlBeanDefinitionReader 父类
AbstractBeanDefinitionReader。
在
AbstractBeanDefinitionReader 构造方法 中将其成员属性 ResourceLoader resourceLoader 实例化为
PathMatchingResourcePatternResolver。在
PathMatchingResourcePatternResolver 构造方法 中将其成员属性 ResourceLoader resourceLoader 实例化为 DefaultResourceLoader。在 DefaultResourceLoader 中调用 ClassUtils 获取默认类加载器。
在
AbstractBeanDefinitionReader 构造方法 中将其成员属性 Environment environment 实例化为 StandardEnvironment。
执行流程·XmlBeanDefnintionReader 执行加载 BeanDefinition
XmlBeanDefinitionReader#loadBeanDefinitions() 首先对 ClassPathResource 资源 为 Resource 添加编码,需要了解 字符集、编码格式。然后对 Resource幂等校验,最后对 Resource 进行转换 InputSource ,为 SAX解析XML文档 做准备。
获取 XML 验证模式,首先了解 XML的验证模式,然后通过 XmlBeanDefinitionReader 成员属性 XmlValidationModeDetector#detectValidationMode() 获取 XML 验证模式。
获取 EntityResolver(获取XML验证模式本地文档),首先接口 EntityResolver 被实例化为 ResourceEntityResolver,super() 实例化其父类 DelegatingEntityResolver。在 DelegatingEntityResolver 构造方法 中持有成员属性 DTD 验证模式资源文件获取方式、XSD 验证模式资源文件获取方式。
执行流程·XmlBeanDefnintionReader 执行 SAX 获取 Document
XmlBeanDefinitionReader#doLoadDocument() 调用成员属性 DefaultDocumentLoader 构造方法,进而调用 DefaultDocumentLoader#loadDocument()。在加载 Document 时,首先 创建 Document 构造器工厂,然后获取 DocumentBuilderFactory factory 对象,最后通过 factory 创建 Document 构造器 ,进而将 InputSource 解析为 Document。
执行流程·XmlBeanDefnintionReader 执行注册 BeanDefinitions
XmlBeanDefinitionReader#registerBeanDefinitions() 注册 BeanDefinition,首先 创建
BeanDefinitionDocumentReader,进而 创建 XmlReaderContext;
在 创建 XmlReaderContext 前了解其成员参数 ProblemReporter 实例化为 FailFastProblemReporter;成员参数 ReaderEventListener 实例化为 EmptyReaderEventListener;成员参数 SourceExtractor 实例化为 NullSourceExtractor;成员参数 NamespaceHandlerResolver 实例化为
DefaultNamespaceHandlerResolver;进而了解 XmlReaderContext 构造方法,super() 其父类为 ReaderContext。
registerBeanDefinitions() 调用 doRegisterBeanDefinitions() 进而调用 createDelegate()。
在 createDelegate() 调用
BeanDefinitionParserDelegate 构造方法,该对象执行 initDefaults() 对
DocumentDefaultsDefinition 类中属性赋值。调用 populateDefaults() 进行属性默认值填充,extractSource() 提取数据源,fireDefaultsRegistered() 完成默认注册,isDefaultNamespace() 判断当前是否是默认命名空间,如果是 获取 profile 属性 并 acceptsProfiles() 校验 profiles 是否合规。
DocumentDefaultsDefinition 实现 DefaultsDefinition,DefaultsDefinition 继承 BeanMetadataElement。
知识体系
结尾共勉
靡不有初而鲜克有终
坚信日拱一卒无有尽,功不唐捐终入海。
檐滴穿石处,忽见青山老。
感谢支持
文章中对已经阐述过的章节会通过链接的方式提供跳转,不再重复阐述,如果需要查阅,可以点击链接跳转。
如果 APP 端点击跳转链接无法跳转或跳转空白页面,可以进入我的文章中按照文章名称进行检索。或留言,会在评论区提供文档链接。
以上均为个人观点,如有异议或不足,欢迎留言。