前言

说到spring,几乎所有做java后端开发的同学的第一反应不是春天的英语,而是辣个框架,可见spring对我们的影响之深。。。现在不管大厂小厂,国内国外,spring都是大家开发项目的默认依赖框架,spring对我们平时开发的大多数场景都提供了内部实现(如事务,缓存,切面,web等),极大的减少了我们代码的开发量,但正是由于spring对外提供了极大的便捷性,所以其内部必然会做很多处理,其复杂性可见一斑,比如:

web开发中我们标有@RequestMapping注解的接口方法,方法参数可以用一个DTO对象接,也可以用多个字段参数接,还可以加上HttpServletRequest,HttpServletResponse等参数,大家有没有想过spring是怎么实现的呢?
首先spring肯定是通过反射执行的接口方法,而method.invoke(Object obj, Object… args)需要传入所有参数实例,那么spring在构建参数实例列表时,会有大量工作用来解析HttpServletRequest里的前端参数和method Parameters的关系,比如Parameter是个基本类型的,那就可以直接从request.getParameter(参数名)获取对应值;如果是个对象,那就要解析对象的字段…;Parameter上可能还有注解,如@PathVariable…等等,是不是想想都复杂。。。(后面会专门有一篇博客回顾这块的源码)

也正因为我们熟悉了spring的那一套,导致有些基本流程原理都忘了,就更不能理解spring相关的源码实现。

比如事务,相信很多同学用注解时都是迷迷糊糊,其实实现事务就这几点:
1.执行start transaction开启事务
2.业务代码进行数据库操作时始终用的是1中的connection
3.方法执行完commit/rollback
spring无非就是把这些进行了封装 (后面也会专门有一篇博客回顾这块的源码)

本人毕业工作也已近4年,陆陆续续看视频、书籍,结合源码把spring的一些核心功能大概过了遍,看一遍当然不够,所以这次采用边回顾边通过写博客记录学习心得,也谈一谈我对spring有些实现的理解,希望能帮到想要阅读spring源码的同学,比心~~

何为spring

或者说spring主要是干什么的?许多同学可能看了一些面试题,会这样回答:控制反转(IOC)和面向切面(AOP)。我认为太过笼统抽象了,IOC其实是bean为了能实现定制化,所以将参数配置在xml文件中,启动spring时读取xml文件来初始化bean对象的一种叫法;AOP其实就是代理,不能算spring的内核,只是因为切面这个功能我们用起来确实很方便,所以会特别强调AOP。


在表述我的看法前,想问大家个问题:假设现在不用spring,我们项目中那么多service,要想互相能够引用,应该怎么做呢?

答:当然是写一个单例类A,静态成员变量是所有的service,然后在A的初始化方法里初始化所有的service,这样service1要用service2时直接用A.service2即可。

问题貌似解决了,那假如你的这个项目是基础模块,需要通过jar包的方式给其他模块使用呢?首先其他模块也得有一个单例类B来初始化本模块的service,为了使用基础模块的service,还得要知道初始化单例类A,假如这个模块又打成jar包给其他模块使用,那就成了个套娃了,假如单例类A里有些service我不想初始化,因为代码是写死的,我只能自己再写个单例类去初始化。

归根结底,我们就是需要一个类来管理(初始化和存放)service(也可以是任意类),当我需要某个类的实例时,可以直接从这个类里取,而spring其实就是维护了一个bean name->bean的map(容器),而bean为了能拓展,比如修改接口实现类class,字段值,就需要使用配置化文件(如xml)暴露这些属性,自然而然地,spring启动时会读取这些配置文件再初始化bean,这样我们在代码中的任意位置,想要使用注册了的bean时,就能直接从spring容器中根据名称获取(@Resource注解实际就是这个作用)

所以下一篇文章就开始从spring容器开始解读源码,然后按照平时开发使用频率最高的功能模块依次讲解,暂定顺序为

  1. spring事务
  2. spring AOP
  3. springMVC
  4. jdbc