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



系列教程


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

上面代碼中<construct-arg ref="weapon"/> 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類的子類之間的依賴關系是松耦合的。

可以看到依賴注入的技術基礎是多態機制與反射機制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM