Spring源码阅读-IOC

一、IOC指的是什么?

       个人愚见,IOC我们知道的是控制反转,也就是我们把bean的创建和销毁交给容器,这是字面意思的理解。简单的理解方式,就是spring启动的时候把你需要的bean提前创建好,放到一个容器,可以理解成一个map,

之后需要用到某个bean的时候,你不需要再new一个对象,而是可以直接从存放了bean的map中获取就好。当然了,我也说了,这是为了初学者方便理解,实际上的spring IOC容器的和spring bean比这复杂很多。

       复杂表现在哪些地方呢?

      (1)普通bean和spring bean的区别在什么地方?

      (2)哪些bean会在容器启动时候创建好?

        (3)  一个bean的创建要经历哪些阶段?

        别急。这些问题都会在往后的分析中一一解答。

 

二、spring源码分析架构

         我们需要知道BeanFactory就是一个顶层的IOC容器,当然了,我们最常用的是它的子类ApplicationContext。

因为BeanFactory只是实现了一个IOC容器最基础的一些功能,我们可以通过子类扩展来实现更加丰富的功能。我们可以看到AppllicationContext还实现了好多其他接口。

这样就是为了扩展功能。

        好了,我们现在就开始分析源码吧。具体的源码下载和编译构建大家可以参考其他博客,这里就不再赘述了。要熟悉一下Gradle构建工具。

这就是我们的的测试类。要开始进入源码了。

         1、要先初始化父类,然后解析配置文件,也就是application.xml文件

        2、最重要的是refresh这个方法,这个是容器启动最核心的方法。你会发现spring在校验方面做的也很好,比如在refresh之前先校验refresh状态。如果是启动状态,才能进行refresh。这看着很没必要,但是因为spring启动一个IOC容器是一个很繁琐的过程,链路很长,所以校验这步骤其实是很有必要的。而且还加了锁,看下面这段。

 

         3.我们先看prepareRefresh()这个方法,功能我在上图中已经写了。具体细节我们再深入了解一下。

        4.环境准备好,那下一步我们需要做的就是创建bean的流程了,我们知道spring肯定不会一个一个创建bean,可能会有一个工厂类,所以我们应该生成一个beanFactory工厂,用来创建一个一个的bean。是的,就是下面这个方法。beanDefitionRigistory如何理解呢?你可以理解为一个map缓存,主要用来解决循环依赖的问题。这个我们后面会说到。跟着源码debug进去。

           5、根据上图我们可以知道,默认创建的是DefaultListableBeanFactory工厂类。创建工厂类之后就是设置一些属性,然后装载beanDefition,这步骤比较重要,我们可以来看一下。其实就是通过xml解析器来读取配置文件。然后封装成beanDefition注册。

          6、太多细节的东西我们不看了,我们继续看主要流程。这几步大家看我的注释。我解释一下,这几步主要是后置处理器,一个是工厂beanFatory的后置处理,一个是bean的后置处理,那后置处理有什么好处呢,我们可以通过实现BeanFactoryPostProcessor 

和BeanPostProcessor 来装载后置处理,这就意味着我们在外部写的类只要实现这两个类,那我们在外部写的逻辑就可以影响到容器内部初始化过程。那我们之后对spring的使用中就可以扩展功能。

            7、我们看最后最重要的一步,第十一步,这才是真正的bean实例化步骤。我们已经在创建beanFactory的时候把beanDetition注册到一个beanDefitionRigistory,或者可以说一个map缓存,我们直接实例化就好了。

具体的实现细节需要大家再去深入了。

       好了,我们说回开头的三个问题。

       springBean与普通bean的区别?

       其实是springBean经历了上面描述的整个周期,这样的bean才能称为spring bean。

       而如何解决循环依赖问题呢?

       我们知道spring实例化bean其实默认是用bean的无参构造器来实例化的。所以如果我们是构造函数中循环依赖,那我们是没法解决的。但是如果是@Autowored依赖 我们在生成beanDefination的时候就可以生成一个beanFactories三级缓存(工厂对象池),之后依赖时候直接从单例池(一级缓存)获取发现获取不到就会去二级缓存获取,如果还是获取不到,那三级缓存中的工厂类会生产出这个单例或者单例的代理类放到二级缓存中。那及时生产出来的单例没有走完生命周期,但是可以提前暴露在二级缓存。就解决了循环依赖的问题。也称为提前暴露。咱们看源码吧。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值