这是Spring源码解读的开篇讲解,本章节主要介绍面试中相关Spring问题的回答方向,以及我们之后会从哪些方面着手去讲解Spring源码;
当然也包括了Spring源码前期的一些小问题(BeanDefinitionReader、BeanDefinition)的解读;
面试
当我们在面试的时候,面试官可能会问一些比较回答面比较“广泛”的问题,例如:请谈谈你的Spring的理解;
1.先宏观的去进行解答,面对这种问题的时候我们不仅需要答出IoC、DI、AOP这三个核心思想,更要提到它们分别是做什么的,例如IoC控制反转、DI依赖注入、AOP面向切面编程;
2.在使用层面去进行解答,例如我们可以给面试官说,我们平时使用Spirng更多的是将其作为容器来使用,是用来帮我们承载具体的Bean对象的容器;
3.深入的往设计层面去解答,去介绍Spring是怎么来设计这个容器的以及如何发挥对应作用的;
4.往生态层面去解答,例如我们在企业中使用的SpringBoot,SpringCloud等等这些框架都是依赖Spring而扩展开发的,而Spring在整个生态里面就是一个基石的角色;,它的生态是比较完整的;
5.因此我们在回答这种问题的时候都要从总=>分去谈我们的理解;例如我们可以先总的说IoC、DI、AOP,然后再去说它们分别是什么有什么用,然后再慢慢扩展到它是怎么实现的,以及一些难点,例如生命周期、循环依赖等等
源码前瞻
1.我们都知道Spring是一个用来存储Bean对象的实例的,那么它是怎么存储的呢?它的底层是用什么集合框架来存储的呢?
2.我们在获取Bean对象的时候都知道使用ApplicationContext上下文对象的getBean方法去获取对象,那它是怎么获取的呢?
3.像面试里面经常问到的Spring的循环依赖问题,大家都知道Spring内部有一个三级缓存来解决的,那它是怎么解决的呢?三级缓存又是什么呢?
4.我们在创建Bean对象的时候需要告诉Spring需要创建什么对象,我们可以以XML文件的形式,也可以以注解的形式,那这两种形式Spring是如何进行解析进而得到的呢?
其实无论在XML中还是在注解中,我们都是按照Spring的规范去提供bean的定义信息;
这些定义信息都被存放在BeanDefinition这个Map结构的对象中去, 这个BeanDefinition就是一个接口,它定义了一系列的具体的规范(set、get方法)去设置或者获取到具体的属性;
这些Bean的定义信息,我们可以定义成properties文件、可以定义成json格式的文件、也可以定义成yaml格式的文件,因此在创建BeanDeifinition对象之前Spring还提供了一个接口去解析这些文件,而这个接口里面就需要去定义一系列的约束和规范;因此如果我们后面要使用其他配置文件的时候,我们只要实现好当前这个接口 ,那么Spring就可以解析不同格式的配置文件了;这个十分重要的接口叫BeanDefinitionReader;
因此我们可以发现,Spring提供了非常非常多的接口和抽象类供我们使用,而这些就体现Spring强大的扩展性;
抽象类和接口的本质区别
接口:自上向下(我们在定义接口的时候是不需要考虑子类的实现的,因为子类只要实现了这个接口就必须去实现这些规范,因此是自上向下的)
抽象类:自下向上( 而我们在定义抽象类的时候,是发现了子类的一些共性,进而将其抽取出来作为一个抽象类,因此在定义抽象类之前必须要考虑子类的共性,因此是自下向上的)
我们在创建出BeanDefinition对象之后,这个对象中存储的是Bean的定义信息而并不是Bean对象,紧接着的事情就应该是创建出Bean对象=>使用Bean对象=>销毁Bean对象;
因此我们需要围绕上面三点及其扩展性去进行分析和研究;