Spring的核心思想之IOC:仿Spring自定义一个实现IOC的容器

  IoC Inversion of Control (控制反转/反转控制),是⼀个技术思想而不是⼀个技术实现。它描述的是Java开发领域对象的创建,管理的问题 ——传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象,而在 IoC思想下开发⽅式:使用者不⽤⾃⼰去new对象了,由IoC容器(Spring框架或其他)帮助使用者实例化对 象并且管理它,使用者需要使⽤哪个对象,去问IoC容器要即可。

  在这个过程中使用者丧失了⼀个权利(创建、管理对象的权利),同时得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列事情) 为什么叫做控制反转呢?

     控制:指的是对象创建(实例化、管理)的权利

     反转:控制权交给外部环境了(spring框架、IoC容器)

  在五、仿MyBatis自定义的持久层如何添加增删查改功能实现了一个仿Mybatis的框架,其基本思路是:

    1、解析配置文件至响应数据结构

    2、Executor进行操作,并保存结果到相应数据结构中。

  通过研究相关资料以及类似实现自定义访问持久层的思路,也实现了一个自定义的IOC,代码地址https://gitee.com/duckinpool/homework_2021/tree/master/1.2_spring/code/。大致目录如下:

                    

  其大致思路也是:1、解析文件,保存数据到内存数据结构中。

          2、读取数据结构中数据并根据它们实例化对象,并保存到内存数据结构中(即所谓的容器中)。

  其过程呢,大致如下:

          

  通过上面注解和代码分析可得:

    1、保存解析文件的数据结构为beanDefinitions,其本质就是一个列表List<LFBeanDefinition>。而LFBeanDefinition则是保存了类名及类路径。  

          

    2、根据BeanDefinition实例化。

          

      通过代码可知实例化本身逻辑比较明晰,如果在已存在这个类名,就直接获取这个对象;如果没有就newInstance这个类同时保存到这个Cache中。那么这个Cache究竟是什么呢?

          

      Cache本质就是一个Map,即此处自定义容器已经完成了IOC的基本工作。

      需要注意的是除了该Cache外还有个Cache——factoryBeanInstanceCache——这个Cache有何用呢?自动注入中继续分析。

    3、自动注入。

      该过程相对复杂是因为在这个过程中细节比较多,特别需要关注的是依赖注入DI(DI中可能涉及动态代理——敲重点)。

          

    getBean代码如上图,图中绿框部分逻辑为:如果在factoryBeanObjectCache中没有——即没有实例化,则没有该类对象。如果有,而factoryBeanInstanceCache中没有,则将自动注入后的对象put进去,最后返回的也是factoryBeanInstanceCache中的对象。

    综上所述,factoryBeanInstanceCache就是使用者获取待使用对象的容器。那么自动注入的过程就是在put factoryBeanInstanceCache之前的代码中体现:即populateBean方法 完成了对Bean属性的依赖注入。

          

    关于BeanPostProcessor本文中不关注(不是本文中阐述IOC的内容),关注的只有populateBean这段。

          

          

    可以看到对factoryBeanObjectCache中的instance利用JKD中反射为其field注入factoryBeanInstanceCache中的对应对象。

    本文中DI实现使用的是递归的模式,同时也没有展现出DI过程中可能涉及到的动态代理(其中涉及Spring中三级缓存)。总言之,本文中的自定义容器基本实现了Spring容器的简单功能,底层机构类似。后续研究Spring框架结构可以重点研究下DI过程中涉及动态代理的实现,以及三级缓存相关使用(参考Spring的核心思想之DI:详解Spring DI循环依赖实现机制)。

 

posted on 2024-03-12 16:20  池塘里洗澡的鸭子  阅读(40)  评论(0编辑  收藏  举报