zoukankan      html  css  js  c++  java
  • 【设计模式】依赖注入

    前言

    依赖注入(Dependency Injection,DI)是控制反转原理(Inversion of Control,IoC)的实现方式之一。依赖注入在构建依赖项复杂且多的对象时,优势就很明显了,比如 Grafana 项目在构建 Service Graph 就用到了依赖注入,来梳理复杂的依赖图。

    依赖注入

    依赖注入对象与其依赖项的关联是通过装配器(Assembler)来完成,而不是对象自己创建依赖。

    比如,一个传统的创建依赖对象的代码例子如下。Store 类的依赖对象 item 是类自己创建的。

    public class Store {
        private Item item;
      
        public Store() {
            item = new ItemImpl1();    
        }
    }
    

    利用依赖注入的思想,我们可以把上面代码改造如下。别看代码很普通、很习以为常。但确是实现了依赖注入,Store 类不再关心 item 对象的创建。最后,更高级的玩法是,通过一个依赖项的 metadata 配置信息或文件来创建对象,而不是直接传入一个实例

    public class Store {
        private Item item;
        public Store(Item item) {
            this.item = item;
        }
    }
    

    构造函数注入 vs Setter 方法注入

    构造函数注入(Constructor-Based Dependency Injection,CDI)和 Setter 方法注入(Setter-Based Dependency Injection,SDI)是两种常见的依赖注入方式。两个 Java Spring 中的例子为例:

    CDI 例子

    代码:

    package com.geeksforgeeks.org; 
      
    import com.geeksforgeeks.org.IGeek; 
      
    public class GFG { 
      
        // The object of the interface IGeek 
        IGeek geek; 
      
        // Constructor to set the CDI 
        GFG(IGeek geek) 
        { 
            this.geek = geek; 
        } 
    } 
    

    依赖项配置文件:

    <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-2.5.xsd"> 
      
        <bean id="GFG" class="com.geeksforgeeks.org.GFG"> 
            <constructor-arg> 
                <bean class="com.geeksforgeeks.org.impl.CsvGFG" /> 
            </constructor-arg> 
        </bean> 
          
    <bean id="CsvGFG" class="com.geeksforgeeks.org.impl.CsvGFG" /> 
    <bean id="JsonGFG" class="com.geeksforgeeks.org.impl.JsonGFG" /> 
              
    </beans> 
    

    SDI 例子

    代码:

    package com.geeksforgeeks.org; 
      
    import com.geeksforgeeks.org.IGeek; 
      
    public class GFG { 
      
        // The object of the interface IGeek 
        IGeek geek; 
      
        // Setter method for property geek 
        public void setGeek(IGeek geek) 
        { 
            this.geek = geek; 
        } 
    } 
    

    依赖项配置文件:

    <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-2.5.xsd"> 
    
    	<bean id="GFG" class="com.geeksforgeeks.org.GFG"> 
    		<property name="geek"> 
    			<ref bean="CsvGFG" /> 
    		</property> 
    	</bean> 
    	
    <bean id="CsvGFG" class="com.geeksforgeeks.org.impl.CsvGFG" /> 
    <bean id="JsonGFG" class="com.geeksforgeeks.org.impl.JsonGFG" /> 
    		
    </beans> 
    

    总结

    依赖注入的概念其实很简单,具体运用起来有很多灵活的变式。

    参考资料

    [1] Intro to Inversion of Control and Dependency Injection with Spring
    [2] Spring Dependency Injection with Example

  • 相关阅读:
    Python常用内置函数整理(lambda,reduce,zip,filter,map)
    C#中Hashtable容器的了解与使用
    关于ref与out的区别
    关于多线程学习总结(五) 线程池
    关于多线程学习总结(四) 锁
    关于多线程学习总结(三) 线程简单基本操作
    关于多线程学习总结(二) 了解线程的属性及方法
    关于多线程学习总结(一) 基本概念了解
    CSS文件和Javascript文件的压缩
    看几道JQuery试题后总结(下篇)
  • 原文地址:https://www.cnblogs.com/huanggze/p/12539600.html
Copyright © 2011-2022 走看看