我当了十年了码农了,接触spring也有十年了,spring在是我们java程序员的开发神器,有了它,我们再也不用为创建对象和维护对象之间的关系而烦恼了,那么spring是如何创建对象,并管理对象了呢,今天我们来聊聊,创建对象依赖原始数据结构之BeanDefinition对象。
spring容器把它所认识的对象,从最初的beanDefinition对象到最终的bean对象,经历了过程,可以说是非常的漫长的.想要spring容器管理对象,你首先得让你的这个对象变成一个beanDefinition对象。那我们该怎么变成beanDefinition呢,在spring最初的版本中,我们在xml文件标签中定义一些类的配置信息,这个xml配置信息的结构,就是beanDefinition对象的数据结构。它有哪些属性,都在标签有所定义,比如说,对象的ID,对象的class限定名称,类的初始化方法,等等,这些属性也就是beanDefinition对象的属性,那么spring可以根据beanDefinition对象的属性,创建一个真正意义上属于spring容器管理的对象。我接下了来讲讲spring如何开始加载这个xml文件的。
如果你想要使用spring里面的对象,你就不得不获得spring的上下文对象,在它的构造方法中,有一个开始启动容器工作的方法,那就是大名鼎鼎的refresh方法,这个方法,就是spring启动容器初始化的整个过程都在这个方法中,我们这里先说说加载xml变成beanDefinition对象的这块内容。
在refresh方法中,加载xml文件的基本流程上,首先让这个xml文件变成一个spring能认识的资源resource文件,然后再将这个resource文件交给一个叫xmlBeanDefinitionReader对象中的loadDefinitions方法进行解析,这个过程就是读取器,读取文件,很形象.在loadDefinitions方法中,是会先将resource文件的内容封装成,document对象,这个解析封装的过程就是java原生的sax方式解析xml,任何xml文件都可以使用它的原生方法,只不过spring使用的是拿来主义,直接使用了他的sax的api方式进行解析而已。我们拿到了docement对象后,就是一个document树,我接下来就是要做的,解析这个document上的各种节点了。
来到了解析document树的环节后,这颗树上有什么呢,就是创建一个对象需要的东西。我们把这些东西全部都拿到,放到beanDefinition中,在spring创建对象的时候,就从它里面拿就可以了。在spring最初的版本中,其实就只有beans和bean,import标签,,没有后来所谓的context,aop等标签。但是后来由于版本的升级,功能的增多,逐渐增加了许多各种各样的标签,这些新增的这些标签,最终只有一个目的,那就是让我们定义的bean的时候更舒服,更方便而已。比如说你要使用事务,最开始的时候,我们定义的声明事务的类起码有transactionMananger 还要配置datasource,还要配置你业务类的哪些方法使用到了事务,等等这些信息. 有了aop这个标签之后,你只需要一行就可以搞定这个配置的,非常的方便。我们把bean的标签成为,spring原始标签,把context,aop等标签成为扩展标签,所以解析的时候,分为原始标签的解析和扩展标签的解析。在原始标签解析中你会看到各种从document的标签中,获得属性,往beanDefinition对象里面进行设置,在解析扩展标签的时候,这个地方有点意思,非得值得大家在开发中进行借鉴。接下我要说这个扩展标签的有意思的地方在哪里。
在扩展标签解析的流程中,会首先找到spring.factors这个文件并进行加载,并且解析,这个文件,定义了各种标签,和解析类的映射关系,我们把解析解析后的内容,标签和解析放到一个map容器中进行管理,等到你解析的标签是指定的扩展标签的时候,那么就会从这个map中获得指定的解析类,进行处理,而这些解析类都有一个叫init方法,这个方法加载存放的是,各自标签对应的子标签的解析器.所以说啊。先拿到标签解析器,在拿到这个标签子标签解析器,然后再执行它的pasre方法完成解析标签,设置到beanDefinition的中去,一个扩展标签是由标签和子标签组成的。这种从配置类中获得处理类的方式我们成为spi思想,你完全可以把这个思想用到自己的项目中去。
好了,关于beanDefinition对象我先聊到这里,谢谢大家的观看 谢谢。