简单谈谈Spring的IoC
一、前言
这几天正在复习Spring
的相关内容,同时想要对Spring
的实现原理做一些深入的研究。今天看了看Spring
中IoC
的实现,找到了一篇非常详细的博客,研究了一个下午,看完之后唯一的感受就是——太复杂了。Spring
源码中,类和接口的体系非常的复杂,同时方法的实现也是,方法调用感觉无穷无尽,甚至相互调用,给我绕的晕晕的。应该是自己目前的技术水平还太低,项目经验也不足,甚至对Spring
的运用都不够熟悉,所以研究源码对我来说可能还是太早了。
虽然对于Spring
的IoC
,我可能连十分之一都还没有弄懂,但是一个下午的研究也不是毫无收获。这篇博客就来简单讲讲我对IoC
的理解,以及Spring
中,IoC
最基本的实现流程。
二、正文
2.1 什么是IoC
在我们使用传统的编码方式编写代码时,如果在类中需要引用另外一个类的对象,我们一般会直接在类中使用new
关键字,创建这样一个对象。此时,使用这个对象的类,就与这个对象所对应的类产生了耦合性。
IoC
中文名称为控制反转,它就是用来解决上述问题的一种设计思想,它能指导我们设计出耦合性更低,更易于管理的代码。传统的程序,都是在需要使用的地方主动地创建对象,而IoC
的思想却是将创建对象的工作交给IoC
容器去进行。我们告诉IoC
容器,它需要创建那些对象,IoC
容器创建好这些对象,然后主动地将它们注入到需要使用的地方。此时,需要使用对象的那些类,并不主动地获取对象,而且由IoC
容器为它们分配,控制权在IoC
容器手上,这就是控制反转。当然,IoC
容器并不只是控制对象,可以理解为控制外部资源的获取。
IoC
很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC
容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
2.2 IoC和DI的关系
DI
中文名称为依赖注入,它其实和IoC
是相同的概念,或者可以理解为它是IoC
的一种具体的实现方式。IoC
的概念可能比较模糊,控制反转只是一种思想,可能仅仅只是停留在由其他组件控制对象,而不是在使用的地方直接创建这一层面,但是具体如何实现并没有指明。而DI
就是它的一种实现思路,由容器创建对象,并主动将对象注入到需要使用它的地方。2.1
中对IoC
的解释,实际上更加偏向于DI
。
2.3 Spring如何实现IoC
这一块,我就简单地说一说我今天下午在研究Spring
的IoC
源码的过程中,了解到的一些内容。首先,Spring
的IoC
容器,可以简单地理解为就是BeanFactory
接口的一个实现类对象,比如Spring
的应用上下文接口ApplicationContext
就是继承自BeanFactory
,而我们使用较多的ClassPathXmlApplicationContext
就是ApplicationContext
的一个实现类。它们都可以理解为是Spring
的IoC
容器,而BeanFactory
就是这个继承体系中的最高层。下面我就以单例bean的创建,简单地说一说Spring
的IoC
实现的一个过程,假设使用到的是ClassPathXmlApplicationContext
这个容器,解析的是xml
配置文件:
- 容器解析
xml
配置文件,将声明在xml
文件中的bean
的配置信息提取出来,每一个bean
的配置信息被封装成一个BeanDefinitionHolder
对象。BeanDefinitionHolder
主要包含三个成员——BeanDefinition
对象,bean
的名称(id
),以及bean
的别名。BeanDefinition
对象就是用来保存一个bean
的配置信息,比如bean
的作用域,bean
的类型,bean
的依赖,bean
的属性...... - 容器创建一个
ConcurrentHashMap
对象,这个map
的key
是bean
的名称,而value
则是BeanDefinition
对象的引用。容器将第一步中解析出的每一个BeanDefinitionHolder
对象,它对应的bean
名称,以及拥有的BeanDefinition
引用放入这个map
中。所以,这个map
保存了我们在程序中声明的所有的bean
的配置信息。 - 容器初始化完成后,开始创建
bean
,遍历第二步中的map
集合,获取到bean
的名称以及对应的BeanDefinition
对象,通过BeanDefinition
对象中的信息,判断这个bean
有没有定义为延迟加载,若没有,则需要现在就进行创建。在创建前,先通过BeanDefinition
中的配置信息,判断此bean
有没有depend-on
(依赖)其他bean
,若有,则先创建当前bean
依赖的bean
(此处的depend-on
不是bean
的属性,而是需要通过配置项进行配置的)。之后,则创建当前遍历到的bean
。 bean
在创建完成后,通过bean
的BeanDefinition
对象,获取bean
需要注入值的属性,然后为属性赋值,若属性的值类型是其他的bean
,则以上面相同的步骤,创建属性对应的bean
;- 容器创建一个
ConcurrentHashMap
,将创建好的单例bean
保存在其中。我们在代码中可以通过容器的getBean
方法,传入bean
的名称或类型获取单例bean
。容器会先去这个map
中查找,若map
中不存在,且这个bean
的配置在第2
步中存储配置信息的map
中能够找到,则创建这个bean
,放入存储bean
的map
中(因为bean
可以配置延迟加载,即第一次获取时加载);
Spring
中,bean
最基本的两种作用域就是singleton
(单例)和prototype
(多例),默认为单例。以上过程是单例bean
的创建过程,若作用域为prototype
,则每一次调用getBean
方法,都会创建一个新的bean
。顺带一提,创建bean
的方式是通过反射机制,这个大部分人应该都知道。
三、总结
以上内容是我根据自己的认识,对Spring
的IoC
做的一次简单记录,内容并不全面,因为我目前对它的理解也比较浅显。在今天阅读Spring
源码的过程中,我发现它真的比我想象中要复杂很多,或许是我水平有限,又或许是没有掌握阅读源码的方法,读起来真的非常吃力。总而言之,想要真正读懂Spring
,我还需要很多的学习,希望今后能够尽快提升自己,早日将Spring
吃透。
四、参考
简单谈谈Spring的IoC的更多相关文章
- 简单理解Spring之IOC和AOP及代码示例
Spring是一个开源框架,主要实现两件事,IOC(控制反转)和AOP(面向切面编程). IOC 控制反转,也可以称为依赖倒置. 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B, ...
- 谈谈Spring的IoC之注解扫描
问题 IoC是Inversion of Control的缩写,翻译过来即"控制反转".IoC可以说是Spring的灵魂,想要读懂Spring,必先读懂IoC.不过有时候硬着头皮 ...
- 简单解析Spring核心IOC容器原理
将大体流程解析了一边,具体可以看源代码一个方法一个方法的跟下 XmlBeanFactory的功能是建立在DefaultListableBeanFactory这个基本容器的基础上的,并在这个基本容器的基 ...
- 谈谈Spring中的BeanPostProcessor接口
一.前言 这几天正在复习Spring的相关内容,在了解bean的生命周期的时候,发现其中涉及到一个特殊的接口--BeanPostProcessor接口.由于网上没有找到比较好的博客,所有最后花了好 ...
- JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP、IOC)
接上篇<JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构.调试.部署>,通过一个简单的JSP WEB网站了解了JAVA WEB相关的知识,比如:Ser ...
- Spring框架-IOC和AOP简单总结
参考博客: https://blog.csdn.net/qq_22583741/article/details/79589910 1.Spring框架是什么,为什么,怎么用 1.1 Spring框架是 ...
- 谈谈Spring Ioc的理解
原文:http://blog.csdn.net/qq_22654611/article/details/52606960 学了几天Ioc了,但是对它的理解还是模模糊糊,看了这篇博客感觉对Ioc有了更深 ...
- spring中IOC的简单使用
spring的ioc主要就是依赖注入,有基于构造器的依赖注入还有通过设值注入,这里我只简单的实现设值注入的方法,通过spring的依赖管理,我们可以很方便的了解各层之间的依赖关系,降低了各层之间的耦合 ...
- (反射+内省机制的运用)简单模拟spring IoC容器的操作
简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...
随机推荐
- Extjs入门——环境配置
Extjs框架作为一个07年就上线的框架,虽然与现在的框架对比,显得十分臃肿.但是在针对企业内部引用系统上,它依旧能发挥出不错的效果.现在我接触到了Extjs,所以我准备写一个入门框架,简单的介绍Ex ...
- 在Python中该如何实现Java的重写与重载
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:清风python PS:如有需要Python学习资料的小伙伴可以加点击 ...
- window 10 安装paddlepaddle 1.7 GPU版本
window 10 安装paddlepaddle 1.7 GPU版本 1)更新显卡驱动 2)安装cuda 10 https://developer.nvidia.com/cuda-10.0-downl ...
- 本地同时使用多个git账号
config文件说明 Git Document指示在首次安装git的时候需要配置Config的相关内容信息,有三个地方存储了config文件,决定了读取的场景不同. 1 /etc/gitconfig: ...
- redis: 事务管理(九)
redis的事务 不保证原子性 三个步骤:开启事务.命令入队.执行事务 开启事务:multi 执行事务:exec 127.0.0.1:6379> multi #开启事务 OK 127.0.0.1 ...
- Spring Cloud Gateway+Nacos,yml+properties两种配置文件方式搭建网关服务
写在前面 网关的作用不在此赘述,举个最常用的例子,我们搭建了微服务,前端调用各服务接口时,由于各服务接口不一样,如果让前端同事分别调用,前端同事会疯的.而网关就可以解决这个问题,网关屏蔽了各业务服务的 ...
- 用 Python 获取百度搜索结果链接
前言 近期有许多项目需要这个功能,由于Python实现起来比较简单就这么做了,代码贴下来觉得好点个赞吧~ 代码 # coding: utf-8 import os import time import ...
- mybatis源码学习:插件定义+执行流程责任链
目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...
- Vue 3.0 Composition API - 中文翻译
Composition API 发布转载请附原文链接 https://www.cnblogs.com/zgh-blog/articles/composition_api.html 这两天初步了解了下 ...
- VUE前端项目配置代理解决跨域问题
VUE前端项目配置代理解决跨域问题 问题如下,经常在本地调试接口出现这种问题 解决方式1:Chrome 的扩展插件 以前使用Chrome 的扩展插件,但是有时候还是会出现莫名其妙的问题. 需要梯子才行 ...