通俗易懂————依赖注入

spring中核心就是一个轻量级控制反转(IOC)和面向切面编程(AOP)的框架!
其中控制反转就是为了降低代码之间的耦合度,最常见的方式是依赖注入

什么是依赖注入?

我们先看看什么叫依赖。在生活中,依靠别人或者别的事物而不能独立或者自立,我们称为依赖。

那么在应用中,什么叫依赖呢? 依赖指的是两个实例之间的关系。其中一个实例是独立的,另一个实例是非独立的(依赖的),它依靠另外一个实例。比如计算机对象,它包含主机对象和显示器对象。如果没有主机对象或者显示器对象,则计算机对象就是不完整的,不能正常使用,我们就说计算机对象依赖于主机对象和显示器对象。

那么什么是注入呢? 计算机对象离不开主机对象和显示器对象,程序在运行过程中,我们必须给计算机对象提供它所需要的主机对象和显示器对象,把主机对象和显示器对象像“打针”一样提供给计算机对象,这个过程就叫做注入。 也就是说,如果一个对象需要另外一个对象才能正常使用,我们在程序运行的时候,给该对象提供它所需要的对象,这就是“依赖注入”。

我们知道,Spring将会管理几乎所有的Bean对象,而对象与对象之间可能存在依赖关系,在程序运行过程中,Spring把我们所需要的对象都拼装好,这就是Spring的依赖注入。 在传统的 Java设计中,当 Java实例的调用者创建被调用的 Java实例时,要求被调用的 Java类出现在调用者的代码中,二者之间无法实现松耦合。通俗说就是工厂模式则对此进行了改进,使调用者无须关心被调用者的具体实现过程,只要获得符合某种标准 (接口)的实例即可使用。其调用的代码面向接口编程,支持调用者与被调用者解耦,因此工厂模式得以大范围地使用。但在工厂模式中,调用者需要自行定位工厂,与特定工厂耦合,所以仅在一定程度上实现了调用者与被调用者的解耦。Spring 的出现使调用者无须自行定位工厂,当程序运行至需要被调用者时,系统将自动提供被调用者实例。事实上,调用者与被调用者均由 Spring管理,二者之间的依赖关系由Spring提供。

通俗来说就是:class A 中用到了class B 对象 一般情况下需要在A类中new一个B对象 采用依赖注入只需要在A类中定义一个私有的B 对象

依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。

依赖注入综合案例
  • 如何开发一个打印机?
    可灵活配置使用彩色墨盒或黑色墨盒
    可灵活配置打印页面的大小(A4、B5)
    打印机功能的实现依赖于墨盒和纸张
  • 步骤
    1.定义墨盒和纸张的接口标准
    2.使用接口标准开发打印机
    3.组装打印机
    4.运行打印机

1.定义墨盒和纸张的接口标准

//定义墨盒接口
public interface InkBox {
    
    
    //提供获取颜色的方法
    String getColor();
}
============== 为了阅读方便放在了一起 标准做法应该要分开写 ==============
//定义纸张大小接口
public interface PaperSize {
    
    
    //提供获取纸张大小的方法
    String getPaper();
}

2.接口的实现类

//A4纸张
public class A4Paper implements PaperSize {
    
    
    public String getPaper() {
    
    
        return "A4";
    }
}
//B5纸张
public class B5Paper implements PaperSize {
    
    
    public String getPaper() {
    
    
        return "B5";
    }
}
//黑色墨盒
public class BlackInkBox implements InkBox {
    
    
    public String getColor() {
    
    
        return "黑色墨盒";
    }
}
//彩色墨盒
public class ColourInkBox implements InkBox {
    
    
    public String getColor() {
    
    
        return "彩色墨盒";
    }
}

3.打印机类(这里定义类就可以了,如果还想组装不同的打印机,就要使用到接口,不同的打印机类去实现了一个公共的打印机方法)

Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。

public class Printer {
    
    
    private InkBox inkBox;
    private PaperSize paperSize;
	//通过set注入必须要提供无参构造
    public Printer() {
    
    
    }
	//提供setter方法对应xml文件中标签<property name="paperSize" ref="a4Paper"/>
    public void setInkBox(InkBox inkBox) {
    
    
        this.inkBox = inkBox;
    }
    //提供setter方法对应xml文件中标签<property name="inkBox" ref="colourInkBox"/>
    public void setPaperSize(PaperSize paperSize) {
    
    
        this.paperSize = paperSize;
    }
    //组装打印机的方法
    public void print(){
    
    
        System.out.println("使用"+inkBox.getColor()+"打印出了"+paperSize.getPaper()+"大小的纸张");
    }
}

4.配置applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 创建A4Paper的对象 -->
    <bean id="a4Paper" class="com.li.bean.Impl.A4Paper"/>
    <!-- 创建ColourInkBox的对象 -->
    <bean id="colourInkBox" class="com.li.bean.Impl.ColourInkBox"/>
    <!-- 创建Printer对象 Printer中用到了PaperSize InkBox 两个接口的引用 所以需要接口的实现类-->
    <bean id="printer" class="com.li.bean.Printer">
        <property name="paperSize" ref="a4Paper"/>
        <property name="inkBox" ref="colourInkBox"/>
    </bean>

    <bean id="b5Paper" class="com.li.bean.Impl.B5Paper"/>
    <bean id="blackInkBox" class="com.li.bean.Impl.BlackInkBox"/>
    <bean id="printer2" class="com.li.bean.Printer">
        <property name="paperSize" ref="b5Paper"/>
        <property name="inkBox" ref="blackInkBox"/>
    </bean>
</beans>

5.测试

public class TestPrinter {
    
    
    /**
     * 一般情况下:new 对象
     */
    @Test
    public void printerOut() {
    
    
        A4Paper a4Paper = new A4Paper();
        ColourInkBox colourInkBox = new ColourInkBox();
        Printer printer = new Printer();
        printer.setPaperSize(a4Paper);
        printer.setInkBox(colourInkBox);
        printer.print();
        //使用黑色墨盒打印出了A4大小的纸张
    }

    /**
     * 创建对象由配置文件管理
     */
    @Test
    public void printerOut2(){
    
    
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Printer printer = context.getBean("printer", Printer.class);
        printer.print();
        //使用彩色墨盒打印出了A4大小的纸张
    }

    @Test
    public void printerOut3() {
    
    
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Printer printer = context.getBean("printer2", Printer.class);
        printer.print();
        //使用黑色墨盒打印出了B5大小的纸张
    }
}

总结:Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。

猜你喜欢

转载自blog.csdn.net/lirui1212/article/details/108977147