一、控制反轉(zhuǎn):縮寫IoC
是一種設(shè)計(jì)原則,降低程序代碼之間的耦合度
對象由Ioc容器統(tǒng)一管理,當(dāng)程序需要使用對象時直接從IoC容器中獲取。這樣對象的控制權(quán)就從應(yīng)用程序轉(zhuǎn)移到了IoC容器
二、依賴注入:縮寫DI
依賴注入是一種消除類之間依賴關(guān)系的設(shè)計(jì)模式。例如,A類要依賴B類,A類不再直接創(chuàng)建B類,而是把這種依賴關(guān)系配置在外部xml文件(或java config文件)中,然后由Spring容器根據(jù)配置信息創(chuàng)建、管理bean類。可以簡單的理解為給對象賦值
兩種實(shí)現(xiàn)方式:
1、構(gòu)造方法注入(非主流了解即可)
Spring容器調(diào)用構(gòu)造方法注入被依賴的實(shí)例,構(gòu)造方法可以是有參的或者是無參的。Spring在讀取配置信息后,會通過反射方式調(diào)用實(shí)例的構(gòu)造方法,如果是有參構(gòu)造方法,可以在構(gòu)造方法中傳入所需的參數(shù)值,最后創(chuàng)建類對象。
步驟:
編寫用戶類User類,在User類中定義id、name和password三個屬性
創(chuàng)建applicationContext-User.xml文件,在該文件中添加User類的配置信息
編寫測試類:創(chuàng)建測試類TestUser,用于測試依賴注入的結(jié)果
編寫用戶類User類
public class User {
private int id; private String name; private String password;
public User(int id, String name, String password){
this.id=id; this.name=name; this.password=password; }
public String toString(){
return "id="+id+",name="+name+",password="+password; }}
配置信息中使用到<constructor-arg>元素
具體介紹如下:
一個<constructor-arg>元素表示構(gòu)造方法的一個參數(shù),且定義時不區(qū)分順序,只需要通過<constructor-arg>元素的name屬性指定參數(shù)即可。<constructor-arg>元素還提供了type屬性類指定參數(shù)的類型,避免字符串和基本數(shù)據(jù)類型的混淆。
例如:
<bean id="user" class="com.itheima.User">
??????? <constructor-arg name="id" value="1">
??????? </constructor-arg>
??????? <constructor-arg name="name" value="張三">
??????? </constructor-arg>
??????? <constructor-arg name="password" value="123"></constructor-arg>
</bean>
測試類代碼
public class TestUser {
??? public static void main(String[] args)throws Exception{
?????? ?//加載applicationContext.xml配置
??????? ApplicationContext applicationContext=new
??????? ClassPathXmlApplicationContext("applicationContext-User.xml");
?????? ?//獲取配置中的User實(shí)例
??????? User user=( User)applicationContext.getBean("user");
??????? System.out.println(user);
??? }
}
2、屬性setter方法注入(主流注入方法)
步驟
編寫用戶類User類,在User類中定義id、name和password三個屬性并且注明setter方法
創(chuàng)建applicationContext-User.xml文件,在該文件中添加User類的配置信息
編寫測試類:創(chuàng)建測試類TestUser,用于測試依賴注入的結(jié)果
?編寫用戶類User類
public class User {
private int id;
private String name;
private String password;
public void setId(Integer id){
this.id=id;
}
public void setUsername(String username){
this.username= username;
}
public void setPassword (String password){
this. password = password;
}
public String toString(){
return "id="+id+",name="+name+",password="+password; }
}
創(chuàng)建applicationContext-User.xml文件,在該文件中添加User類的配置信息,
在類中注明setter方法,在配置文件中使用property(屬性的意思)元素
<bean id="user" class="com.itheima.User">
<property name="id" value="2"></property>
<property name="name" value="李四"></property>
<property name="password" value="456"></property>
</bean>
property屬性使用
name的屬性值準(zhǔn)確的講不是屬性名,而是set方法去掉set關(guān)鍵字后的名字
屬性名idàsetter方法setIdd();去掉關(guān)鍵字setà即idd(駝峰命名)
測試類:
public class TestUser {
??? public static void main(String[] args)throws Exception{
?????? ?//加載applicationContext.xml配置
??????? ApplicationContext applicationContext=new
??????? ClassPathXmlApplicationContext("applicationContext-User.xml");
?????? ?//獲取配置中的User實(shí)例
??????? User user=( User)applicationContext.getBean("user");
??????? System.out.println(user);
??? }
}
三、依賴注入和控制反轉(zhuǎn)的比較
依賴注入(DI)和控制反轉(zhuǎn)(IoC)是從不同角度來描述了同一件事情。
依賴注入是從應(yīng)用程序的角度描述,即應(yīng)用程序依賴IoC容器創(chuàng)建并注入它所需要的外部資源;而控制反轉(zhuǎn)是從IoC容器的角度描述,即IoC容器控制應(yīng)用程序,由IoC容器反向地向應(yīng)用程序注入應(yīng)用程序所需要的外部資源。這里所說的外部資源可以是外部實(shí)例對象,也可以是外部文件對象等。
四、對降低程序代碼之間的耦合度的解釋:
在傳統(tǒng)模式中如果使用一個類,自然的做法是創(chuàng)建一個類的實(shí)例:
class Player{?
??? Weapon weapon;?
??? Player(){?
??????? // 與 Sword類緊密耦合
??????? this.weapon = new Sword();?
??? }?
??? public void attack() {
??????? weapon.attack();
??? }
}??
這個方法存在耦合太緊的問題,例如,玩家的武器只能是劍Sword,而不能把Sword替換成槍Gun。要把Sword改為Gun,所有涉及到的代碼都要修改,當(dāng)然在代碼規(guī)模小的時候這根本就不是什么問題,但代碼規(guī)模很大時,就會費(fèi)時費(fèi)力了。
運(yùn)用依賴注入的方式降低耦合的示例:
class Player{?
??? Weapon weapon;?
??? // weapon 被注入進(jìn)來
??? Player(Weapon weapon){?
??????? this.weapon = weapon;?
??? }?
??? public void attack() {
??????? weapon.attack();
??? }
??? public void setWeapon(Weapon weapon){?
??????? this.weapon = weapon;?
??? }?
}??
如上所示,Weapon類的實(shí)例并不在代碼中創(chuàng)建,而是外部通過構(gòu)造函數(shù)傳入,傳入類型是父類Weapon,所以傳入的對象類型可以是任何Weapon子類。
傳入哪個子類,可以在外部xml文件(或者java config文件)中配置,Spring容器根據(jù)配置信息創(chuàng)建所需子類實(shí)例,并注入Player類中,如下所示:
??? <bean id="player" class="com.Springyx.demo.Player">
??????? <construct-arg ref="weapon"/>
??? </bean>
????
??? <bean id="weapon" class=" com.Springyx.demo.Gun">
??? </bean>
上面代碼中<construct-arg ref="weapon"/>?ref指向id="weapon"的bean,傳入的武器類型是Gun,如果想改為Sword,可以作如下修改:
??? <bean id="weapon" class=" com.Springyx.demo.Sword">
??? </bean>
只需修改這一處配置就可以。文章來源:http://www.zghlxwxcb.cn/news/detail-827742.html
注意:松耦合,并不是不要耦合。A類依賴B類,A類和B類之間存在緊密耦合,如果把依賴關(guān)系變?yōu)锳類依賴B的父類B0類,在A類與B0類的依賴關(guān)系下,A類可使用B0類的任意子類,A類與B0類的子類之間的依賴關(guān)系是松耦合的(即創(chuàng)建中間商)文章來源地址http://www.zghlxwxcb.cn/news/detail-827742.html
到了這里,關(guān)于Spring學(xué)習(xí)筆記(二)Spring的控制反轉(zhuǎn)(設(shè)計(jì)原則)與依賴注入(設(shè)計(jì)模式)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!