Spring框架通过Xml文件方式加载注册BeanDefinition的全链路分析
2020-06-15 11:41:04 1 举报
登录查看完整内容
Spring框架通过Xml文件方式加载注册BeanDefinition的全链路流程图
作者其他创作
大纲/内容
1.创建Document对象,用来解析XML文件2.解析dom树,即解析出一个个的属性,并将其保存到BeanDefinition中3.调用registerBeanDefinitions方法向容器注册BeanDefinition
AbstractBeanDefinitionReader类
extends AbstractXmlApplicationContext
1.利用BeanDefinitionParserDelegate对象实例化BeanDefinitionHolder对象,BeanDefinitionHolder是对BeanDefinition的封装类,其中有BeanDefinition实例,还有beanName和别名信息2.调用registerBeanDefinition方法开始向容器中注册BeanDefinition实例3.注册完成后发布注册成功的事件
调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识
DefaultBeanDefinitionDocumentReader类
AbstractApplicationContext类
1.校验经过之前N多步解析出的beanDefinition是否是AbstractBeanDefinition的实例2.将beanName作为key,从beanDefinitionMap中get一下,看是否已经被注册过,如果该beanName的实例已经被注册过,就根据配置信息进行处理,允许的情况下就覆盖实例3.判断容器现在是否已经开始注册Bean实例,如果已经开始创建,说明不是第一次全量初始化BeanDefinition信息,此时就增量注册BeanDefinition;如果没有创建Bean实例,那么直接对其进行更新即可3.1 动态增量注册BeanDefinition:使用同步代码块,锁住beanDefinitionMap,将要注册的BeanDefinition实例put进去,然后将新增的实例与原有的实例的信息一起合并再更新进容器3.2 静态注册BeanDefinition:由于容器还没有实例化Bean,直接将要注册的BeanDefiniton信息put进去就可以,不需要额外操作4.清空此次注册的BeanDefinition的beanName同名且已经注册过的BeanDefinition缓存和单例的Bean实例,重置新注册的BeanDefinition相关的parent,或者把此次注册的BeanDefinition当做parent的BeanDefinition
调用构造函数,将资源路径字符串数组configLocations传进去,支持批量加载路径
loadBeanDefinitions(XmlBeanDefinitionReader reader)方法
obtainFreshBeanFactory();
extends DefaultResourceLoader\t\timplements ConfigurableApplicationContext
AbstractRefreshableApplicationContext类
AbstractXmlApplicationContext类
进入Xml文件的解析阶段,解析BeanDefinition信息
都发生在refresh()方法中
1. 获取ResourceLoader2.判断ResourceLoader是批量加载器还是单个资源加载器(判断是否为ResourcePatternResolver)3.根据不同策略进行加载
loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法
告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动
加载BeanDefinition阶段
Spring框架通过Xml文件方式加载注册BeanDefinition的全链路分析
1.创建BeanDefinitionDocumentReader,这个是实际从XML的DOM树中读取BeanDefinition的2.获取注册表BeanDefinitionMap在本次加载前的BeanDefinition数量3.加载并注册,最终调用doRegisterBeanDefinitions方法
进入BeanDefinition实例化阶段与注册阶段
XmlBeanDefinitionReader类
implements BeanDefinitionDocumentReader
1.销毁并关闭容器(如果有) 2.创建容器实例3.对容器进行定制化 4.加载BeanDefinition5.将BeanFactory设置为Spring容器的内部BeanFactory
ApplicationContext applicationContext = new FileSystemXmlApplicationContext(xmlPath);
extends AbstractApplicationContext
环境准备阶段
调用静态代码块ContextClosedEvent.class.getName();用来加载系统环境信息,根据操作系统加载环境
loadBeanDefinitions(EncodedResource encodedResource)
refreshBeanFactory()方法
调用重载方法来进行第5步
构造函数中调用
init阶段
doRegisterBeanDefinitions(Element root)
setConfigLocations(configLocations);用来处理路径,比如替换占位符等
表示下一步,一般是进入下一个方法或者跳转别的类
1. 创建XmlBeanDefinitionReader 2. 加载资源环境3.注入ResourceLoader 4.定制化reader5.利用BeanDefinitionReader开始加载bean definitions
extends AbstractBeanDefinitionReader
通过Xml文件加载BeanDefinition的具体逻辑就在这个方法中1.从ThreadLocal中获取当前的正在加载的资源,保证多线程的线程安全2.获取文件输入流并设定编码3.调用doLoadBeanDefinitions开始解析xml文件
FileSystemXmlApplicationContext类
refresh()方法
根据init阶段得到的configLocations开始加载BeanDefinition
DefaultListableBeanFactory类
processAliasRegistration(Element ele)
容器初始化(刷新)阶段
对当前类或者方法的注释
进入Xml文件的定位与加载阶段
调用重载方法来进行加载
loadBeanDefinitions(String... locations)
加载BeanDefinition并返回加载的BeanDefinition数量
表示当前方法中进入别的方法或者类,后面所有方法都在该方法内进行调用,调用结束后还会回到该方法进行下一步
注册
prepareRefresh();
0 条评论
回复 删除
下一页