也谈Spring之依赖注入DI/控制反转IOC

首先提问: 什么是 Spring IOC 容器?

        Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。

然而,依赖注入到底是什么?

        依赖注入(Dependency Injection):两个对象之间的依赖关系在程序运行时由外部容器动态的注入依赖行为方式称为依赖注入简称DI。

        在依赖注入中,您仅需声明,不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IoC 容器将它们装配在一起。

        控制反转:是一种将组件依赖关系的创建和管理置于程序外部的技术。
        由容器控制程序之间的关系,而不是由代码直接控制,由于控制权由代码转向了容器,所以称为反转。
        对象与对象之间的关系可以简单的理解为对象之间的依赖关系,举例:在类 A 的方法中需要调用类 B 的方法来完成功能,那么首先在 A 类需要有类 B 的一个实例,叫做 A 类依赖于B 类。
        一个需要特定的依赖的组件一般会涉及一个依赖对象,在 IOC 的概念中叫做目标 (target) 。换句话说, IOC提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务,用这种方法与它的依赖进行交互。总的来说, IOC能够被分解为两种子类型:依赖注入和依赖查找。

那么,可以通过几种方式完成依赖注入?

通常,依赖注入可以通过三种方式完成:

        1) 构造函数注入

        2) setter 注入

        3) 接口注入

        在 Spring Framework 中,仅使用构造函数和 setter 注入。

注入方式:区分构造函数注入和、setter 注入

构造函数注入setter 注入
没有部分注入有部分注入
不会覆盖 setter 属性会覆盖 setter 属性
任意修改都会创建一个新实例任意修改不会创建一个新实例
适用于设置很多属性适用于设置少量属性

接着,Spring 中有多少种 IOC 容器?

       1)BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。

       2)ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能。

区分 BeanFactory 和 ApplicationContext。

BeanFactoryApplicationContext
它使用懒加载它使用即时加载
它使用语法显式提供资源对象它自己创建和管理资源对象
不支持国际化支持国际化
不支持基于依赖的注解支持基于依赖的注解

再然后,IoC 可以带来哪些好处?

IoC 的一些好处是:

        1)减少代码量。

        2)它将使应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制。

       3)它以最小的影响和最少的侵入机制促进松耦合。

       4)它支持即时的实例化和延迟加载服务。

最后,给出Spring IoC 的实现机制。

Spring 中的 IoC 的实现原理就是工厂模式加反射机制。

示例:

package com.spring;

/**
 * Created by Liuxd on 2018-11-11.
 */
interface Animal {
    public abstract void speak();
}

class Cat implements Animal {
    public void speak() {
        System.out.println("I am a cat");
    }
}

class Dog implements Animal {
    public void speak() {
        System.out.println("I am a dog");
    }
}

class BeanFactory {
    public static Animal getInstance(String ClassName) {
        Animal f = null;
        try {
            f = (Animal) Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

public class Client {
    public static void main(String[] a) {
        Animal animal = BeanFactory.getInstance("com.spring.Cat");
        if (null != animal) {
            animal.speak();
        }
        Animal animal2 = BeanFactory.getInstance("com.spring.Dog");
        if (null != animal2) {
            animal2.speak();
        }
    }
}

打印结果:

I am a cat
I amd a dog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春风化作秋雨

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值