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

举报
mikechen的互联网架构 发表于 2024/11/03 20:59:10 2024/11/03
【摘要】 本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。

关注△mikechen的互联网架构△,10年+BAT架构经验倾囊相授

image.png

大家好,我是 mikechen | 陈睿

IOC 属于 Spring 的核心内容,如果想掌握好 Spring ,你肯定需要对 IOC 有足够的了解 @ mikechen

image.png

IOC的定义

IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。

IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。

传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试,有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,如下图所示:

image.png

上图引入了IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器。

所以,IOC借助于“第三方”实现具有依赖关系的对象之间的解耦,使程序更优良。

IOC与DI的关系

其实IOC包括依赖查找(DL)和依赖注入(DI),只不过DL因为有侵入性 (它需要用户自己去是使用 API 进行查找资源和组装对象),已经被抛弃。

所以现在提到IOC,更多的想到的就是依赖注入(DI)了,如图所示:

image.png

DI的全称是Dependency Injection,中文称之为依赖注入,它与控制反转(IOC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。

当某个Java对象(调用者)需要调用另一个Java对象(被调用者,即被依赖对象)时,在传统模式下,调用者通常会采用“new 被调用者”的代码方式来创建对象,如图所示:

image.png

这种方式会导致调用者与被调用者之间的耦合性增加,不利于后期项目的升级和维护。

在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。

这样,控制权由应用代码转到了Spring容器,控制权发生了反转,这就是Spring的控制反转IOC。

从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入,如图所示:

image.png

依赖注入方式

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)或者注解来描述类与类之间的关系。

这样我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了,如下图所示:

image.png

IOC容器和对象的创建过程如下:

1.先创建BeanFactory容器

2.加载配置文件,封装成BeanDefinition

3.调用执行BeanFactoryPostprocessor

准备工作;

准备BeanPostProcessor;

准备监听器、事件、广播器;

4.实例化

5.初始化

6.获取到完整对象。

以上,是IOC的详细解析,欢迎评论区留言交流或拓展。

我是 mikechen | 陈睿 ,关注【mikechen的互联网架构】,10年+BAT架构技术倾囊相授。

本文已同步我的技术博客 www.mikechen.cc,更新至我原创的《30W+字大厂架构技术合集》中。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。