那天有人问我:“IOC到底啥用,感觉用处不大,还特麻烦!”那天有人问我:“IOC到底啥用,感觉用处不大,还多一些麻烦!”
关于IOC的话题,已经很多很多了,但是很多都处于了解,或者仅仅使用于框架上,这里我分享一些自己的理解,然后实现一个类似spring ioc 的东西。
一、什么是IOC
维基百科上说到:2004年Martin Fowler 提出了“控制反转的”概念,他得出的结论是:依赖对象的获得被反转了。后来为这个创造了一个更好的名字:依赖注入(IOC = Inversion of Control).简单的解释是:系统的运作是通过两个或多个类的合作来实现业务逻辑,这使得每个对象都需要与其合作的对象的引用(依赖关系),这个依赖对象以前是通过自身实现去获得,现在通过一个容器统一的管理这些依赖关系,从而获得这种依赖的这种实现方式,我们可以成为IOC。
二、为什么要用IOC
我们知道任何事物的诞生,总会有其目的,这里我们先模拟几种场景,让我们更清楚的了解IOC是如何诞生的。
例1: A类 需要用到业务B类的引用,这时候我们在A 里面进行 B b = new B();随着系统的庞大,我可能后面 C,F,G...N 都要用B类的引用,我们在每个类里面都进行类似A的操作吗?好吧,你这样做了!但是突然有一天需要变化,B类我们必须要一个带参构造public B(Stirng str){}.那么你要把所有的类的引用全部修改一次吗?如果可能继续扩展,继续变化呢?
例2:同样很多类都需要B类的引用,B是A接口的实现,我现在不想用实现类B了,从新实现一个类C,全部替换过来,那么你需要从N 个类里面进行修改吗?
例3:大部分情况下类的关系是:A需要B,B需要C,C需要D,D需要...!然后经常的变动是:B不满足了,需要改变,或者替换,然后可能D也需要替换等,然后我们就各个地方到处更改吗?
说道这里,我们先看看按原始方式做的优劣:
优点:
1.速度快,写得舒服!
缺点:
1.创建太多对象,占用内存空间。
2.维护麻烦,改动可能影响太多的类
当然可能大家会反驳,单例模式和工厂模式能解决那些缺点。当然熟悉工厂模式的朋友知道,即使是通过反射生成类的动态工厂,也需要提供路径参数,在在使用这些工厂的时候,我们依然会出现类似于硬编码的问题,不好管理。因此IOC诞生了。
IOC 基本上也是动态工厂和单例等的结合体,并将类路径移植到配置文件,它带来的好处很多。
1.统一管理文件,一个接口多个实现,替换更改方便
2.同时可以监控类的生命周期,和一些其他属性
3.让我们程序解耦,代码量减少,无需关心具体实现,更多的去关注业务逻辑
4.这种可拔插的模式,更符合OOP的那些原则。
5.我们测试,也更加方便,类也能更好的复用了。
当然也有一些坏处:
1.让我们的生成对象的步骤变得麻烦,初学可能有点不习惯。
2.反射效率稍微低点,但是现在的优化影响不大
三、自己实现IOC框架
这里是解析spring 源码写的,同时也会对spring IOC 源码进行分析,为了更让我熟悉IOC原理,以及实现。
我们所说的IOC 主要是两个部分,IOC容器和DI注入,这是两个独立的步骤。
IOC容器又分为:
a.Resource 定位:这是一个通用的数据来源对象,也就是说先要找到资源
b.载入数据:将找到的数据进行载入到内存,形成POJO 对象,这里是定义的BeanDefinition 对象,它 会装在我们需要的数据
c.注册:IOC容器的注册,就是将那些数据注入进BeanDefinition 中,进行集中管理
在写代码之前先进行简单设计:
a. 资源设计:
1.Resource 接口:该接口的目的是统一资源,也就是说无论是网络、本地文件等上的资源,最终都 会以Resource 的形式获得,这里采用策略模式,由具体实现去管,可以屏蔽资源的差异性。
2.AbstractResource 抽象类:对Resource 的抽象实现,实现接口一部分简单的功能
3.ClassPathResource 实现类:我们这里仅仅实现类路径加载的文件资源,更多参考图例:
b.Resource加载器:上面的设计可以让我们获得资源,然后通过加载器进行加载 装配
1.ResourceLoader 接口:这里会通过Resource getResource(String location)获得各种资源,然 后再让各种装载器的实现,去加载,也是策略模式
2.DefaultResourceLoader 实现类:对ResourceLoader的实现,实现一部分基础功能
c.Reader 读取器:这里我们主要用Reader进行 对上述资源的解码
1.BeanDefinitionReader接口:提供对资源装载的基本方法接口
2.AbstractBeanDefinitionReader 抽象类:对上面接口的抽象实现,这里要求具体的实现类进行操作
3.XmlBeanDefinitionReader 实现类:我们这里以xml 的形式进行实现,当然还有properties方式
对资源的读取,也就是loadBeanDefinitions 加载都在这里进行
d.xml(properties) 解析:这里在XmlBeanDefinitionReader 进行实现的,它会将资源信息,解析成 我们需要的Document 对象,这里具体内容可以暂时不管
1.DocumentLoader 接口:定义基本解析方法
2.DefaultDocumentLoader 实现:对资源进行处理,返回Document 对象
e.BeanDefinition 解析:上面我们获得了Document 对象,下面我们要将它转换成BeanDefinition
1.BeanDefinitionDocumentReader 接口:定义了解析方法
2.DefaultBeanDefinitionDocumentReader 实现:基本方法的实现,完成解析和注册功能,这里的解 析功能是让BeanDefinitionParserDelegate 处理,注册是让另外的处理
3.BeanDefinitionParserDelegate :这个类是专门解析Document 对象,然后完成注册功能
f.Document 解析过程:
事实上,从XmlBeanDefinitionReader 源码分析,BeanDefinition 的载入过程,分为xml 解析返回Document ,然后再对document 进行解析的,BeanDefinitionParserDelegate 会专门对Document 对象进行解析操作,对里面的所有Element、Attribute 都进行解析,检查,当然 代码写到这里,我表示解析过程比较复杂、繁琐。我就没写了。也即是通过这里完成了IOC POJO 的载入功能
g.BeanDefinition 在IOC 注册:
1.DefaultListableBeanFactory IOC容器:这里其实很简单,仅仅对刚才获得的BeanDefinition放到 一个new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>> 里面,就完成注 册了,就让这个容器具有了基本的功能,但是还没有完成注入过程。
h.IOC 对象实例化:IOC 注入一般发生在getBean 阶段,当然可以根据lazy-init 属性就行预实例化
1.AbstractBeanFactory :这个基类里面会有getBean 的实现。这里的取值方式从缓存-->工厂-->双亲 工厂(链) 进行获取,同时会递归获取所有依赖的bean.
2.AbstractAutowireCapableBeanFactory: 这个类是createBean的方法所在,当然里面通过各种解析
,最终都由InstantiationStrategy 接口的 instantiate 进行实例化。
3. InstantiationStrategy 接口:提供了instantiate 方法,提供了反射和Cglib的生成方式
4.SimpleInstantiationStrategy 实现类:这里主要是反射,通过构造器 生成对象
5.CglibSubclassingInstantiationStrategy :继承了上面的类,这里通过cglib 进行生成,关于用
cglib 生成类的方式,在aop 学习里面已经有了。
I:IOC 注入:bean 实例化后,就会对他们之间的关系进行设置了。
这里还是会回到AbstractAutowireCapableBeanFactory,因为它会调用上面的类,实例化bean,同时 组装依赖关系还是在里面进行。
1.populateBean 方法:这个方法包会解析BeanDefintion 中Property 的值,然后调 applyPropertyValues方法,对获得的property 放到我们BeanWrapper 中,进行具体的注入过程会 在实现类BeanWrapperImpl 进行,会进行各种属性值的设定。
2.BeanDefinitionValueResolver :从名字可以看出,这个类是解析BeanDefinition 关系的具体实现,上 面的方法的解析,就是调的这个类。这里会对Reference、set等 包含这些属性的进行解析,准备下面 的注入。
3.BeanWrapperImpl :上面的都是准备,这里就会完成真正的属性注入。这里主要会 调setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv)方法,通过getPropertyValue中 获得的属性引用,进行赋值操作。这就完成了整个注入过程。
小结:
1.这里仅仅对spring IOC 实现过程,以及用到主要类进行了介绍,需要详细了解的需要自己进行源码分析,我在实现过程受到spring 都得影响,又想简单实现,结果导致整个设计比较大,也比较乱,看来还无法灵活掌握整个设计和实现,仅仅能从源码分析实现过程和基本原理,这里代码就不分享了。
2.回顾IOC 的整个过程,主要是分为:Resource资源定位,bean 信息的载入、IOC 容器的注入三大过程,然后对每个过程又进行了更细的划分,希望能对这块有个整体上的概念。
3.如果有时间的朋友可以自己尝试按这个逻辑进行写一个IOC,我相信对OOP OOD 都会有更深的理解,也会领略spring 在 这块的设计的优美。当然如果初学的人不建议这样做,其实这块从以前学习使用,到分析,到现在慢慢理解,经历了1年多的过程。我相信随着自己技能的提升,我以后还会分析类似的东西,直到我能随意驾驭、创造的程度,成为一名真正的设计师和架构师。
4.整个过程,可能主要是文字的东西,看着比较枯燥,根据我的经验,即使加上流程图,只要你不自己花时间去了解和分析,还是会很飘,因此再次建议有时间自己去详细分析,这里仅仅介绍思路。
5.上面是自己分析spring 3.2 以及一些知识点介绍,总结出来的,如果有不当的地方,还请多多指点,十分感谢。
相关推荐
- **多态的实现:** 通过覆盖(overriding)和重载(overloading)来实现多态。 - **抽象类与接口:** 区分抽象类和接口的特点与使用场合。 ##### 1.7 抽象类、接口和包 - **抽象类的定义与使用:** 包含抽象方法的...
246 14.5.2 CORBA和RMI的互操作 247 14.6 小结 248 第15章 Spring框架 249 15.1 Spring 2.0的体系结构 249 15.2 Ioc容器 250 15.2.1 BeanFactory 250 15.2.2 ApplicationContext 252 15.2.3 Beans的生命周期过程 253...
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
log凑字数 12345678910
【毕业设计】java+springboot+vue电影评论网站系统设计与实现(完整前后端+mysql+说明文档+LunW).zip
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
双向全桥LLC谐振变换器与非对称拓扑的双向模型仿真研究:正向LLC与反向LC的变频控制闭环模型在Matlab Simulink及PLECS环境下的应用,双向全桥LLC谐振变换器:非对称拓扑与双向模型的Matlab Simulink及PLECS仿真研究,双向全桥LLC谐振变器仿真,非对称拓扑,双向模型 正向LLC,反向LC 采用变频控制的闭环模型 运行环境包括matlab simulink,plecs等 ~ ,双向全桥LLC谐振变换器仿真; 非对称拓扑; 双向模型; 变频控制; Matlab Simulink; PLECS。,双向全桥LLC谐振变换器仿真研究:非对称拓扑与变频控制模型
Jordan标准型行列互逆方法-程序求解
目前,在复杂任务(如Spider数据集上的文本到SQL转换)中,使用大型语言模型(LLMs)的微调模型和提示方法之间存在显著差距。为了提高LLMs在推理过程中的性能,我们研究了将任务分解为较小子任务的有效性。特别是,我们展示了将生成问题分解为子问题,并将这些子问题的解决方案输入给LLMs,可以显著提高其性能。我们的实验表明,这种方法使三个LLMs的简单少样本性能提高了大约10%,使其准确性接近或超过最先进水平(SOTA)。在Spider数据集的保留测试集中,以执行准确率为衡量标准,最先进水平是79.9,而使用我们方法的新最先进水平为85.3。我们的方法在上下文中学习,比许多经过深度微调的模型高出至少5%。此外,在BIRD基准测试中,我们的方法实现了55.9%的执行准确率,创下了该基准测试保留测试集的新最先进水平
程序可以参考,非常好的思路建设,完美!
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
# 基于FreeRTOS的ARM926EJS实验系统 ## 项目简介 本项目将FreeRTOS移植到基于ARM926EJ S CPU的ARM Versatile Platform Baseboard上,当前版本基于FreeRTOS 10.4.0,后续会随FreeRTOS新版本发布而更新。项目处于早期开发阶段,包含基础的演示任务,可用于学习和研究实时操作系统的基本功能与应用。 ## 项目的主要特性和功能 1. FreeRTOS内核移植实现FreeRTOS内核在ARM926EJ S架构上的移植,支持任务管理、信号量、队列、事件标志、互斥量等功能。 2. 中断处理具备中断服务例行程序,能处理中断事件并切换任务。 3. 任务切换有任务切换机制,支持手动切换和定时器中断切换。 4. 定时器管理可进行定时器的创建、启动、停止、查询等操作。 5. 内存管理实现动态内存分配与释放,支持运行时动态操作。
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
基于MATLAB Simulink R2015b的三电平中性点钳位(NPC)逆变器高级仿真模型,基于MATLAB Simulink R2015b的三电平中性点钳位(NPC)逆变器高级仿真模型,Three_Level_NPC_Inverter:基于MATLAB Simulink的三电平中性点钳位(NPC)逆变器仿真模型。 仿真条件:MATLAB Simulink R2015b,拿后前如需转成低版本格式请提前告知,谢谢。 ,核心关键词:Three_Level_NPC_Inverter; MATLAB Simulink; 仿真模型; R2015b版本。,基于MATLAB Simulink的三电平NPC逆变器仿真模型(R2015b版)
CSDN Matlab武动乾坤上传的资料均是完整代码运行出的仿真结果图,可见完整代码亲测可用,适合小白; 1、完整的代码内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
graph_searcher 机器人路径搜索