理解依赖注入(DI - Dependency Injection)


系列教程

  • Spring 框架介绍
  • Spring 框架模块
  • Spring开发环境搭建(Eclipse)
  • 创建一个简单的Spring应用
  • Spring 控制反转容器(Inversion of Control – IOC)
  • 理解依赖注入(DI – Dependency Injection)
  • Bean XML 配置(1)- 通过XML配置加载Bean
  • Bean XML 配置(2)- Bean作用域与生命周期回调方法配置
  • Bean XML 配置(3)- 依赖注入配置
  • Bean XML 配置(4)- 自动装配
  • Bean 注解(Annotation)配置(1)- 通过注解加载Bean
  • Bean 注解(Annotation)配置(2)- Bean作用域与生命周期回调方法配置
  • Bean 注解(Annotation)配置(3)- 依赖注入配置
  • Bean Java配置
  • Spring 面向切面编程(AOP)
  • Spring 事件(1)- 内置事件
  • Spring 事件(2)- 自定义事件

依赖注入(Dependency Injection, DI)是一种设计模式,也是Spring框架的核心概念之一。其作用是去除Java类之间的依赖关系,实现松耦合,以便于开发测试。为了更好地理解DI,先了解DI要解决的问题。

耦合太紧的问题

如果使用一个类,自然的做法是创建一个类的实例:

class Player{
       
    Weapon weapon;  
    
    Player(){
       
        // 与 Sword类紧密耦合
        this.weapon = new Sword();  
        
    }  
    
    public void attack() {
     
        weapon.attack();
    }
}   

这个方法存在耦合太紧的问题,例如,玩家的武器只能是剑Sword,而不能把Sword替换成枪Gun。要把Sword改为Gun,所有涉及到的代码都要修改,当然在代码规模小的时候这根本就不是什么问题,但代码规模很大时,就会费时费力了。

依赖注入

依赖注入是一种消除类之间依赖关系的设计模式。例如,A类要依赖B类,A类不再直接创建B类,而是把这种依赖关系配置在外部xml文件(或java config文件)中,然后由Spring容器根据配置信息创建、管理bean类。

示例:

class Player{
       
    Weapon weapon;  
    
    // weapon 被注入进来
    Player(Weapon weapon){
       
        this.weapon = weapon;  
        
    }  
    
    public void attack() {
     
        weapon.attack();
    }
    
    public void setWeapon(Weapon weapon){
       
        this.weapon = weapon;  
    }  
}   

如上所示,Weapon类的实例并不在代码中创建,而是外部通过构造函数传入,传入类型是父类Weapon,所以传入的对象类型可以是任何Weapon子类。

传入哪个子类,可以在外部xml文件(或者java config文件)中配置,Spring容器根据配置信息创建所需子类实例,并注入Player类中,如下所示:

	<bean id="player" class="com.qikegu.demo.Player"> 
		<construct-arg ref="weapon"/>
	bean>
	
	<bean id="weapon" class="com.qikegu.demo.Gun"> 
	bean>

上面代码中 ref指向id="weapon"的bean,传入的武器类型是Gun,如果想改为Sword,可以作如下修改:

	<bean id="weapon" class="com.qikegu.demo.Sword"> 
	bean>

只需修改这一处配置就可以。

松耦合,并不是不要耦合。A类依赖B类,A类和B类之间存在紧密耦合,如果把依赖关系变为A类依赖B的父类B0类,在A类与B0类的依赖关系下,A类可使用B0类的任意子类,A类与B0类的子类之间的依赖关系是松耦合的。

可以看到依赖注入的技术基础是多态机制与反射机制。

你可能感兴趣的:(后端,spring,di,依赖注入,控制反转,ioc)