前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入剖析Spring(一)——IoC的基本概念(从面向对象角度介绍)

深入剖析Spring(一)——IoC的基本概念(从面向对象角度介绍)

作者头像
大闲人柴毛毛
发布2018-03-09 17:19:43
6500
发布2018-03-09 17:19:43
举报
文章被收录于专栏:大闲人柴毛毛大闲人柴毛毛

IoC与DI

IoC和DI是Spring的两个核心概念,很多人都把它们视为相同的东西,但事实并非如此。 IoC(Inversion of Control):控制反转。 DI(Dependency Injection):依赖注入。

为了方便理解,先给出结论:

控制反转是目的,依赖注入是实现控制反转的手段。

控制反转是一种面向对象的思想,它是一种宽泛的概念,只要一个类将对它内部状态的控制权交由其他机制去完成即为『控制反转』。控制反转是为了降低类与类之间的耦合度。

而Spring采用依赖注入这一具体的手段来达到控制反转的目的。

依赖注入详解 一个类内部往往有很多成员变量,如:

代码语言:javascript
复制
class A {
    private Person chaimm;
}

上述代码在面向对象中可以描述为:

  • A类和Person类之间存在依赖关系;
  • A依赖于Person;
  • A为依赖类;
  • Perosn为被依赖类;

通常情况下,依赖类需要自己去创建并维护被依赖类的对象,如:

代码语言:javascript
复制
class A {
    private Person chaimm = new Person();
}

但依赖注入的做法是:将被依赖对象的创建与维护工作交由专门的机构,而依赖类中只需要声明所需要的成员变量。 也就是说,依赖类原本需要主动去获取对象,但采用依赖注入后对象由第三方机构提供,自己仅需声明需要什么对象即可。 这样做的目的就是为了降低两个类之间的耦合程度。 PS:在Spring中,那个创建、管理对象的机构就称为『IoC Service Provider』。

但此时还没体现出依赖注入能降低耦合度这一点,只有当依赖注入与面向接口编程结合起来,才能真正发挥依赖注入的优势。接下来先介绍一下『面向接口编程』。

什么是面向接口编程? 一个类依赖其他类的目的是为了获取其他类所提供的服务,可能这种服务有多种实现,我们可能需要根据不同的场景使用不同的实现。此时,我们可以使用多态,将同一功能的多种实现抽象出一个接口,并为所有实现定义一套相同的API。在使用时声明接口类型的变量而非实现类的变量,并将实现类的对象赋给接口变量,最后用接口变量去调用实现类的服务,如:

代码语言:javascript
复制
class A {
    private Super super = new SuperImpl_1();

    public static void main ( String[] args ) {
        // 使用Super提供的服务
        super.method_1();
        super.method_2();
        super.method_3();
    }
}

这样,当想使用SuperImpl_2提供的功能时,只需替换Super的实现类,其他地方不做任何变化:

代码语言:javascript
复制
private Super super = new SuperImpl_2();

上述过程就是面向接口编程的思想:若某一类服务有多种不同的实现,我们需要抽象出一个接口,并在接口中定义一套API。在使用时声明接口类型变量,并用实现类的对象赋值。接下来通过接口类型的变量调用服务即可。当功能发生变化时,仅需替换实现类即可。

在面向接口编程的基础上使用依赖注入的好处 上述过程如果要换一种实现,就必须要修改A类的代码,再重新编译。而使用了依赖注入后,由于依赖类不需要自己创建维护被依赖对象,该过程由IoC Service Provider完成。因此,当需要替换实现类时,只需在IoC Service Provider中修改,被依赖类、依赖类都不会受到影响,此时这两个类是松耦合的。

依赖注入的三种方式

下面介绍三种方式,将被依赖对象注入给依赖类。

1. 构造器注入

将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。

优点: 对象初始化完成后便可获得可使用的对象。

缺点: 1. 当需要注入的对象很多时,构造器参数列表将会很长; 2. 不够灵活。若有多种注入方式,每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函数,麻烦。

2. setter方法注入

IoC Service Provider通过调用成员变量提供的setter函数将被依赖对象注入给依赖类。

优点: 灵活。可以选择性地注入需要的对象。

缺点: 依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。

3. 接口注入

依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。该函数的参数就是要注入的对象。 接口注入中,接口的名字、函数的名字都不重要,只要保证函数的参数是要注入的对象类型即可。

缺点: 侵入行太强,不建议使用。

PS:什么是侵入行? 如果类A要使用别人提供的一个功能,若为了使用这功能,需要在自己的类中增加额外的代码,这就是侵入性。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年02月16日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • IoC与DI
  • 依赖注入的三种方式
    • 1. 构造器注入
      • 2. setter方法注入
        • 3. 接口注入
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档