Spring的IOC与DI的个人杂谈

Spring的IOC与DI的个人杂谈

一、前言

初学者初学Spring框架的时候,往往是伴随着SSM三大框架的学习而了解的。但是这样是不好的,我们应该在任务之余去学习一些本框架一些核心的知识点。
本篇文章便是给大家简单讲解一下Spring的核心之一:IOC(控制反转)和DI(依赖注入)

参考文章

  • 2020spring面试题

二、思考问题(在文章的尾声有我的看法,欢迎大家讨论)

  • spring在框架内部是一个什么样的作用?
  • 为什么很多框架都需要Spring来整合?
  • 如果没有spring可以使用其他的框架吗?

三、概念解析

IOC(控制反转)

  • 定义

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
—————————————————————————————————摘自“百度百科”

如果简单翻译就是:讲代码内部的java对象的创建过程转交给后台,而不是直接通过业务代码的new 关键字进行创建。

  • 作用

  1. 解耦。因为大多数情况下,IOC是面向接口的一种抽象开发。因此通过移交创建对象的过程,可以做到降低实体之间依赖关系。
  2. 灵活性。在spring中由于xml,注解等bean选择方式的存在,我们可以在不修改源代码的情况下快速调整IOC容器内部的javaBean,这就会使得后期业务模块修改变得方便。比如:某一个短信服务的功能即将到期,而我们要更改其他的短信服务,需要切换一套全新的但是接口一致的API。此时我们可以不删除原有的逻辑代码,只需要开发新的代码,并将新模块放置IOC容器,即可。
  3. 提高代码和对象的复用。凡是注入到IOC容器的java对象,几乎都是IOC内部共享的,这样对于某些需要依赖spring-Bean管理的工具类或是全局属性对象,可以通过IOC创建并保存。之后哪块业务需要就进行获取即可。

springioc的作用不仅如此,这三点主要是与我们开发最直接相关的优点。


DI(依赖注入)

  • 定义

组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)
—————————————————————————————————摘自“百度百科”
如果简单翻译就是:DI是一种解决ioc容器生成pojo对象过程中,出现的对象依赖的问题的解决。实际用例可以看“作用”的例子。

  • 作用

是用来实现IOC控制反转的策略之一。主要用于IOC容器内部创建javaBean时,对象内部的依赖关系的实现。
比如:class A 和 class B 都保存到了IOC容器,但是class B对象内部有class A的引入,那么通过这种依赖将A对象注入B对象,使其成为一个完整的pojo。


四、Spring的实现方式

图解

Spring的IOC与DI的个人杂谈_第1张图片
1.IOC容器: 指的就是图中的红色部分。在Spring中主要以BeanFactorContext这两个对象体现
2. Bean对象:紫色部分,IOC容器的重要组成部分。我们所说的依赖注入的过程,就是这些Bean创建过程中,得到体现。除了bean8需要bean2之外,每个bean初始值的赋予也是依赖注入的范畴。
3. 业务逻辑:蓝色部分,这个就是ioc之外业务逻辑(但大部分Web应用的逻辑也都处于ioc之中,例如SSM架构)。但是每个业务里面引用的bean对象,都是从ioc容器内部获取的,这就做到了不需要程序员手动创建java对象
4. 对象装配:黑色箭头,是用来解决IOC内部的bean对象是如何进入逻辑内部的。不是本篇的重点

Spring的实现细节

原理

  1. bean的创建
    通过 工厂+反射 实现ioc容器对其内部bean的获取。
  2. bean的创建
    bean的创建周期和方式有很多种,这里举几个业务中常见的例子。(注解、xml解析、java对象生成)+反射

所以学好反射是很重要的

Ioc容器

  • 组成
    在spring内部提供了两类接口:BeanFactory(bean工厂)和ApplicationContext(运行上下文)
    通过这两个接口的各种实例进行IOC容器的创建。
  • 区别
    BeanFactory和ApplicationContext可以看作包含的关系。Context内部除了有BeanFactory还存在有关整个IOC容器内部创建与业务无关的运行对象等等。
  • 方法细节
public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(String name, Class<T> requiredType);
    Object getBean(String name, Object... args) ;
    <T> T getBean(Class<T> requiredType) ;
    <T> T getBean(Class<T> requiredType, Object... args);
}

这个是从spring源码内部拉出来的,删去不必要的注释和方法,我们发现就是**getBean()**方法,而这也就定下了所有IOC容器的实现要求

DI(依赖注入)

首先依赖注入是要解决bean对象创建完成时,内部属性的注入。说白了就是赋值

  • 实现方式
    1、 含参构造器
    2、set / get方法
    3、接口注入(由于使用的缺点已经在spring4废弃)
  • 进行过程
    这个是要涉及到bean对象的创建的过程,图示如下:
    Spring的IOC与DI的个人杂谈_第2张图片
    Bean声明周期的前两步已经基本实现了DI的过程,所以我们可以看作是通过将bean的创建和注入分开了,这样就可以做到如果如果创建A实例时,B实例没有创建的情况。

五、尾声

现在我们回过头来看前面三个问题。我写出自己的看法(为了不打扰大家的思考我用白色字体书写)

  1. spring在框架内部是一个什么样的作用?
    答:spring在框架内部起到一个地基的作用,在功能上并没有像SpringMVC,Mybatis等框架一样是去专门去做某块功能的。但是它会提供一套编码的规范,一套有利于业务开发及维护的模式,供开发人员使用。而这就是spring-core最基本的作用。
  2. 为什么很多框架都需要Spring来整合?
    答:因为大部分框架都存在大量的默认内置对象和业务逻辑对象,而这些对象的储存与创建刚好可以通过Spring提供容器操作,得到IOC的代码能力的支持。而且同样重要的时,Spring对其他框架的入侵程度几乎可以忽略不记,学习成本小。
  3. 如果没有spring可以使用其他的框架吗?
    答:可以,前面说过spring本身不提供业务的功能服务,其他的功能框架如同插件一般集成到spring上面。所以其他框架是可以独自使用的。注意:spring全家桶不算。

你可能感兴趣的:(Spring学习总结)