1. 程式人生 > >一個簡單的例子說明java中spring框架的依賴注入

一個簡單的例子說明java中spring框架的依賴注入

javaEE 開發中,現在最成熟的框架之一應該就是spring了,spring框架最強大的地方就是實現了依賴注入(也叫控制反轉),最近的一個專案中用的就是 spring框架,spring框架是工廠模式的應用結合了MVC的設計思想,,大家可以看到在spring框架中到處體現工廠模式,下面是一個簡單的例子,
依賴注入早期叫控制反轉,也可以稱反射,他們的意義都相同。當某個 Java 例項(呼叫者)需要另一個Java 例項(被呼叫者)時,在傳統的程式設計過程中,通常由呼叫者來建立被呼叫者的例項。而在依賴注入的模式下,建立被呼叫者的工作(也就是例項化一個類)不再由呼叫者來完成,通常由 Spring 容器來完成,然後注入呼叫者,因此稱為控制反轉,也稱為依賴注入。
1、建立介面:人與斧頭
人,定義一個動作:

package test2;
public interface Person {
public void useAxe();
}

斧頭,定義一個動作:

package test2;

public interface Axe {
public void chop();
}


2、建立介面的實現類:中國人與石斧

中國人

package test2;

public class Chinese implements Person{
/*預設無參構造方法不管為私的還是公有的,都可以訪問,

並且要保證bean中存在可以被外界訪問的無參建構函式*/
private

Chinese(){

};
/*定義需要被使用的斧頭介面,具體使用什麼斧頭這裡不管*/
private Axe axe;
/*定義被注入斧頭的set方法,該方法一定要符合JAVABEAN的標準。在執行時候,
*Sping就會根據配置的<ref local=""/>,找到需要注入的實現類*/
public void setAxe(Axe axe){
this.axe=axe;
}
/*這個時候使用的axe,就不再是介面Axe本身,而是被注入的子類例項,

所以這裡的chop()動作就是具體子類的chop動作*/
public void useAxe() {
axe.chop();
}

}


石斧

package test2;

public class StoneAxe implements Axe {
public void chop() {
System.out.println("石斧慢慢砍");
}
}


3、建立對映配置檔案bean.xml:

<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.sprintframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="chinese" class="test2.Chinese">
<!-- 宣告實現類test2.Chinese中的屬性 -->
<property name="axe">
<!-- 指定其中宣告的屬性,需要用本地的那個id對應的class
這裡local的值為"stoneAxe",表示axe的屬性值在注入的時候,
將會用test2.StoneAxe例項注入,到時在例項類Chinese中使用
axe的時候,實際上呼叫的時候StoneAxe的例項
-->
<ref local="stoneAxe"/>
</property>
</bean>
<bean id="stoneAxe" class="test2.StoneAxe"/>
</beans>


4、測試用例:

package test2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Caller {
public static void main(String[] args) {
Caller caller=new Caller();
caller.doIt();
}
public void doIt(){
String bean=getClass().getResource("bean.xml").toString();
ApplicationContext ctx=new FileSystemXmlApplicationContext(bean);
Person person=(Person)ctx.getBean("chinese");
person.useAxe();
}
}


為什麼說在客戶端呼叫某一個類的時候不需要例項化這個類呢?因為在客戶端先聲明瞭這個類的介面,然後給這個介面一個public的set方法,這樣就相當於例項化了一個實現了這個介面的類,看起來不可思議,實際上很簡單,在spring的配置檔案中宣告這個客戶端呼叫了哪個類,然後spring的ioc容器完成注入工作,spring框架說的這麼牛,實際上做的事情很少,估計更大的貢獻是提出了依賴注入這理念,一個類如果要呼叫其它的類,就必須例項化這個類(除非你在這個類裡寫static方法),傳統的做法必須這樣,這樣的話兩個類之間建立了很強的耦合,而面向物件就是為了降低程式之間的耦合,達到可重用的目的,spring框架就是為了降低耦合而誕生的,用例項化介面來代替例項化實現了這一介面的類,然後在spring的配置檔案中宣告這個介面和類的關心,就可以在客戶端呼叫這個實現類的方法了

  spring最簡單的思想就是這樣的,說起來簡單,在大專案裡面spring框架的用處已經到了不可忽略的地步了,相比 EJB這種侵入性的重量級框架,spring更加精悍,也更加靈活,和struts1.0相比,spring的設計思路更單一,但是spring在 view這一層的表現力遠不如struts,因為struts有強大的標籤庫,struts2.0規範了設計的思路,也很強大,至於hibernate在模型層的作用無可代替,另外hibernate是現在研究最多的框架技術,應該說還在發展階段,現在最新的而版本是hibernate3.2。