搞透 IOC,Spring IOC 看这篇就够了!

IOC与AOP属于Spring的核心内容,如果想掌握好Spring你肯定需要对IOC有足够的了解 @mikechen
IOC的定义
IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。
IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试,有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,如下图所示:
上图引入了IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器。
所以,IOC借助于“第三方”实现具有依赖关系的对象之间的解耦,使程序更优良。
IOC与DI的关系
其实IOC包括依赖查找(DL)和依赖注入(DI),只不过DL因为有侵入性 (它需要用户自己去是使用 API 进行查找资源和组装对象),已经被抛弃。
所以现在提到IOC,更多的想到的就是依赖注入(DI)了,如图所示:
DI的全称是Dependency Injection,中文称之为依赖注入,它与控制反转(IOC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。
当某个Java对象(调用者)需要调用另一个Java对象(被调用者,即被依赖对象)时,在传统模式下,调用者通常会采用“new 被调用者”的代码方式来创建对象,如图所示:
这种方式会导致调用者与被调用者之间的耦合性增加,不利于后期项目的升级和维护。
在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。
这样,控制权由应用代码转到了Spring容器,控制权发生了反转,这就是Spring的控制反转IOC。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入,如图所示:

依赖注入方式
Spring的依赖注入,我们一般使用@Autowired注解来完成,关于依赖注入一般有三种方式:
属性注入、构造器注入、setter方法注入:
1.属性注入
属性注入是大家最为常见也是使用最多的一种注入方式了,代码如下:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper; //...
}
2.Set注入
set 方法注入太过于臃肿,实际上很少使用:
@Service
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
@Autowired
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
3.构造器注入
构造器注入是官方推荐的方式,如下:
@Service
public class UserServiceImpl implements UserService {
private final UserMapper userMapper; @Autowired
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
IOC的优缺点
IOC的优点
实现组件之间的解耦,提高程序的灵活性和可维护性。
IOC的缺点
使用IOC框架产品能够给我们的开发过程带来很大的好处,但是也要充分认识引入IOC框架的缺点,做到心中有数。
- 生成一个对象的步骤变复杂了(其实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。
- 对象 生成因为是使用反射编程,在效率上有些损耗,但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。
IOC的实现原理
IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。
- 原理就是通过 Java 的反射技术来实现的,通过反射我们可以获取类的所有信息(成员变量、类名等等等);
- 再通过配置文件(xml)或者注解来描述类与类之间的关系。
这样我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了,如下图所示:

IOC容器和对象的创建过程如下:
1.先创建BeanFactory容器
2.加载配置文件,封装成BeanDefinition
3.调用执行BeanFactoryPostprocessor
- 准备工作;
- 准备BeanPostProcessor;
- 准备监听器、事件、广播器;
4.实例化
5.初始化
6.获取到完整对象。
以上
作者简介
陈睿|mikechen,10年+大厂架构经验,《BAT架构技术500期》系列文章作者,专注于互联网架构技术。
阅读mikechen的互联网架构更多技术文章合集
Java并发|JVM|MySQL|Spring|Redis|分布式|高并发
搞透 IOC,Spring IOC 看这篇就够了!的更多相关文章
- Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了
目录 引言 构建示例 match operator 参数 analyzer lenient 参数 Fuzziness fuzzniess 参数 什么是模糊搜索? Levenshtein Edit Di ...
- 任务21 :了解ASP.NET Core 依赖注入,看这篇就够了
DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET Core的DI实现以及对实例 ...
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新 ...
- net core体系-web应用程序-4asp.net core2.0 项目实战(CMS)-第二章 入门篇-快速入门ASP.NET Core看这篇就够了
.NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.ht ...
- ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!
想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了! 很多通信系统发展到某种程度都会有小型化的趋势.一方面小型化可以让系统更加轻便和有效,另一方面,日益发展的IC**技术可以用更低的成本生产 ...
- [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了
[译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 本文首发自:博客园 文章地址: https://www.cnblogs.com/yilezhu/p/ ...
- ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
ExpandoObject与DynamicObject的使用 using ImpromptuInterface; using System; using System.Dynamic; names ...
- Vue学习看这篇就够
Vue -渐进式JavaScript框架 介绍 vue 中文网 vue github Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架 库和框架的区别 我们所说的前端框架与库的 ...
- 【转】ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
原文链接:https://www.cnblogs.com/yilezhu/p/9241261.html 引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必 ...
随机推荐
- 【摸鱼神器】UI库秒变低代码工具——表单篇(二)子控件
上一篇介绍了表单控件,这一篇介绍一下表单里面的各种子控件的封装方式. 主要内容 需求分析 子控件的分类 子控件属性的分类 定义 interface. 定义子控件的的 props. 定义 json 文件 ...
- Sentry的安装、配置、使用
前言 上一篇文章介绍了ExceptionLess这个日志收集系统:ExceptionLess的安装.配置.使用 由于ExceptionLess官方提供的客户端只有.Net/.NetCore平台和js的 ...
- Centos7中配置NIS:用户账号管理
NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...
- python jinjia2 高级
高层api class jinja2.Environment([options]) Enviroment:环境,是Jinjia2的核心组件,它包含重要的共享变量,如配置.过滤器.测试.全局变量.模板加 ...
- Axure RP 8 实现 圆角文本框 圆角带筛选的下拉列表框 可自动显示滚动条
刚开始用Axure 会发现 Axure 元件库并不是很齐全,很多元件需要自己想办法解决 或者去网上去找.其实个人建议网上有现成的元件可以就下载就不必花时间去折腾.除非你也想练练手,原型这种东西除非高保 ...
- MySQL金融应用场景下跨数据中心的MGR架构方案(2)
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 如何在多个数据中心部署多套MGR集群,并实现故障快速切换. 上篇文章介绍了如何在多数据中心部署多套MGR集群,并构建集群间 ...
- 技术分析 | 浅谈在MySQL体系下SQL语句是如何在系统中执行的及可能遇到的问题
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 SQL语句大家并不陌生,但某种程度上来看,我们只是知道了这条语句是什么功能,它可 ...
- Normal3类定义
法线的相关操作都在图中,实现部分还是大家自己练习,照着图写代码就行了. 类声明: class Normal3 { public: Normal3(); ~Normal3(); Normal3(ldou ...
- P1980 计数问题 - 记录
P1980 计数问题 题目描述 试计算在区间 1 到 n的所有整数中,数字x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1到11中,即在 1,2,3,4,5,6,7,8,9,10,11中,数字1出 ...
- mybatis 05: mybatis中的动态代理
mybatis中动态代理存在的意义 图示 图示分析 分层说明:界面层为第一层,业务逻辑层(接口层 + 实现层)为第二层,数据访问层(接口层 + 实现层)为第三层 业务逻辑层和数据访问层:分别分两层来开 ...