【设计模式】依赖注入

前言

依赖注入(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

posted @ 2020-03-21 15:34  黄挤挤  阅读(324)  评论(0编辑  收藏  举报