随笔 - 303  文章 - 0  评论 - 3  阅读 - 15万

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   池塘里洗澡的鸭子  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2022-03-12 MongoDB命令之集合数据操作(CURD)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示