Spring源码阅读之准备篇

引言

 目前,在以Java语言主导的项目中,我们会使用各种各样的框架来快速搭建应用,尤其在Java web项目中,我们会经常见到Spring的身影,大部分人只知道怎么使用它,但是不知道它真正的运行原理。本篇文章就来揭秘一下Spring框架的整体面容

我想很多同学和我一样,在学习阅读源码前都或多或少有些疑问,在这里简单总结一下常见的问题。

  1. 看源码既费精力又无聊有啥用呢?

  2. 看完源码对我到底有些好处呢?

  3. 源码从那开始读?怎么读?

  4. Spring容器启动整体流程?

带着这几个问题,来看看阅读源码是如何让我们受益的?

01

读源码有啥用?

从我自己的角度理解,工作一段时间以后,还是在做着重复的CRUD操作,当遇到一些比较怪异的线上故障的时候,不能像别人一样快速定位问题,总是没有头绪,眉毛胡子一把抓;遇到这样的问题多数是因为对运行的系统理解的深度不够,只知其表。所以针对这种情况,我觉得应该深入底层去理解其背后的运行原理是至关重要的。

02


读源码的收益是啥?

从我自己现在的体会来讲,主要有如下:

  • 对系统整体的运行轮廓有一个比较清晰的认知,写代码更加游刃有余

  • 学习一些框架优秀的设计思想

  • 为跳槽做一些知识储备

03


源码从那开始读?

这个就比较简单了,以Spring源码为例。首先下载好源码包,写一些简单的测试用例,利用强大的debug功能调试起来,屡试不爽。在后面的源码阅读都会采用这种办法来“偷窥”其真容

04


Spring的IoC“轮廓”?

解决了我们的基本困惑之后,进去我们的正题,Spring到底是怎么运行起来的呢?在解答这个问题之前,我们先从宏观上看下Spring的“轮廓”,防止在读源码的时候不会一头扎进去出不来,导致很快就放弃了自己当初信誓旦旦立下的flag。我以Spring5.0.7为例展开。大家可以选择一个版本去阅读,整体流程上不会有太大的出入。下面附上我整理的Spring的流程图(画的不好,还请见谅,文末附上搭建测试工程用到的核心依赖配置文件)

对于Spring启动及bean实例化的整体流程如上图,大家先做一个简单的了解。每一步的工作也写明了,需要注意的是,比较重要的四步我使用了红色的椭圆标明了。

Spring的IoC全名是 Inversion of Control,即控制反转,大白话来讲就是由原来我们自己亲手new对象的工作交给了Spring来帮我们做了,我们只在需要指定对象的时候找Spring容器去拿就好了,么简单。

比较重要的几个方法我在这里在列一下:

  • obtainFreshBeanFactory(),其作用是创建Spring容器的工厂,并解析配置文件构建相应的BeanDefinition对象(BeanDefinition会贯穿整个源码阅读,在这里我们把它就叫做Bean定义,bean对象就是用它来实例化的)

  • invokeBeanFactoryPostProcessors(),其作用是调用所有实现了BeanFactoryPostProcessor接口或者是BeanDefinitionRegistryPostProcessor子接口的类,简单理解就是修改BeanDefinition定义的即可

  • registerBeanPostProcessors(),其作用是将实现了BeanPostProcessor接口的类注册到Spring容器中,在后面Bean实例初始化前后的时候调用其实现,简单理解就是要在bean实例初始化前后做一些增加功能即可

  • finishBeanFactoryInitialization(),其作用是创建所有非懒加载(非懒加载的意思就是提前加载好方便;相对应的是懒加载,就是在要使用的)

     

总结

本文主要阐明阅读源码能给我们带来哪些收益,以及Spring容器启动的整体流程概览。下一篇文章我们将会展开如何debug进入源码及第一个重要方法obtainFreshBeanFactory()的实现细节。坚持阅读下去,我会尽自己的努力以最直白的话去阐明Spring的流程。最后欢迎提出意见,共同进步。

附件

maven构建Spring源码调试工程用到的依赖,持续更新中
<dependencies>
    <!-- spring 核心组件中的4个依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>


    <!-- 单元测试Junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章