Spring源码初探-IOC(1)-Bean的初始化

前言

对于一名Java码农来说,Spring真是太重要了。目前Spring的体系已经发展得非常壮大,其底层基石core,beans,context非常牢固。

spring 体系结构图

Bean初始化

个人认为,Spring最原始或者最基础的功能是“容器”,帮你管理着一堆bean的生命周期,任你取用,要想更好的使用Spring,还是得了解Bean的整个生命周期,首先了解Bean的初始化过程。本文采用XML配置文件的方式管理bean,分析XmlBeanFactory对于XML文件的解析过程。废话不多说,先上图:

Spring XmlBeanFacotry解析XML过程(1).jpg

上图给出了XmlBeanFactory将xml配置解析成BeanDefinition的过程,最上面给出的类是在解析过程中涉及到的,首先大致进行一个介绍:

  • Resource:是spring对于资源的一种抽象,因为资源的来源可能很丰富,利于File,Class Path Resource,Url Resource等,进行统一封装,暴露出getInputStream进行统一读取解析
  • Document:这个没啥好讲的,XML文档对象
  • EncodedResource:封装了Resource,指定Resource的编码
  • ReaderContext:Bean Definition解析过程中的上下文对象,封装了Resource、ProblemReporter、EventListener、SourceExtractor等
  • Element:XML中的元素节点对象
  • BeanDefinition:这个接口及其实现类非常重要,他描述了XML中一个bean节点及其子节点的所有属性,将xml中的描述转变成内部的field信息,举例:scope,lazyinit,ConstructorArgumentValues(描述构造器),PropertyValues(描述属性值)等,是一个保罗万象的接口,其子类实现包括GenericBeanDefinition、RootBeanDefinition、ChildBeanDefinition等
  • BeanDefinitionHolder:顾名思义包含了一个BeanDefinition,同时其包含了beanName和aliases,更好的封装了一次
  • BeanDefinitionReader:定义了读取BeanDefinition的接口,主要作用是从Resource中读取Bean定义,XmlBeanDefinitionReader是其具体的实现类
  • BeanDefinitionDocumentReader:定义了从Document对象中解析BeanDefinition并且注册到Registry中设计到的接口,其默认实现类是DefaultBeanDefinitionDocumentReader,主要是被XmlBeanDefinitionReader委派去处理Document对象
  • BeanDefinitionParserDelegate:看到Delegate就知道这个哥们是个受苦的对象,是个最终干活的人,官方定义是“Stateful delegate class used to parse XML bean definitions.* Intended for use by both the main parser and any extension* {@link BeanDefinitionParser BeanDefinitionParsers} or* {@link BeanDefinitionDecorator BeanDefinitionDecorators}.”是用于最终处理XML bean定义的人,它做的可都是脏活累活,import/alias/bean等element以及element的子节点以及属性都是它解析并且填充到BeanDefinition中然后使用ReaderContext中的Registry(实际就是DefaultListableBeanFactory)来将该BeanDefinition注册
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {  
  if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {      importBeanDefinitionResource(ele);   }  
  else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {               processAliasRegistration(ele);   }  
   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {      processBeanDefinition(ele, delegate);   }
   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {      // recurse      doRegisterBeanDefinitions(ele);   }}

上述代码描述了BeanDefinitionParserDelegate对于不同element的解析,脏活累活中非常的一个部分

小结

本文算是小小地总结了一下将XML解析成BeanDefinition的过程中涉及到的一些类,将XML解析出来其实是一个很简单的过程,但是Spring却用了非常多的类。究其原因还是为了考虑扩展性,不断地抽象,不断地将责任委派。这篇文章只介绍了DefaultElement的解析,下篇文章将介绍怎么自定义标签以及Spring怎么解析自定义标签。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JackieZheng

在ssh中利用Solr服务建立的界面化站内搜索---solr2

     继上次匆匆搭建起结合solr和nutch的所谓站内搜索引擎之后,虽当时心中兴奋不已,可是看了看百度,再只能看看我的控制台的打印出每个索引项的几行文字,...

22890
来自专栏Linux驱动

46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1)

1.2然后在drivers\media\rc\keymaps里存了各种不同的键映射文件

25620
来自专栏微信终端开发团队的专栏

iOS微信安装包瘦身

前提 微信经过多次版本迭代,产生不少冗余代码和无用资源。之前微信也没有很好的手段知道哪个模块增量多少。另外去年10月微信开始做ARC支持,目的是为了减少野指针带...

946100
来自专栏腾讯云Elasticsearch Service

Elasitcsearch 底层系列 Lucene 内核解析之 Stored Fields

Lucene 的 stored fields 主要用于行存文档需要保存的字段内容,每个文档的所有 stored fields 保存在一起,在查询请求需要返回字段...

20310
来自专栏Hongten

JSP 二讲

22350
来自专栏Java职业技术分享

老师,Spring 是怎么解决循环依赖的?

循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图:

17300
来自专栏移动开发之家

Dagger2的轻松愉悦解析

  Dagger2,依赖注入框架,一个刚接触时感觉麻烦,用久了就会“嘴上说不要,身体却很诚实”的开发润滑剂(◐‿◑)。(本文为拖更而生)

6810
来自专栏开发技术

spring-boot-2.0.3不一样系列之源码篇 - run方法(四)之prepareContext,绝对有值得你看的地方

  此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。如果大家对springboot的源码有所研...

24520
来自专栏风口上的猪的文章

.NET面试题系列[18] - 多线程同步(1)

多个线程同时访问共享资源时,线程同步用于防止数据损坏或发生无法预知的结果。对于仅仅是读取或者多个线程不可能同时接触到数据的情况,则完全不需要进行同步。

16230
来自专栏JavaQ

高并发编程-CyclicBarrier深入解析

CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到所有线程都到达某个公共屏障点(也可以叫同步点),即相互等待的线程都完成调用await方法...

1.2K30

扫码关注云+社区

领取腾讯云代金券