系列教程
- 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>
上面代碼中<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類的子類之間的依賴關系是松耦合的。
可以看到依賴注入的技術基礎是多態機制與反射機制。