Spring的模塊化是很強的各個功能模塊都是獨立的我們可以選擇的使用這一章先從Spring的IoC開始所謂IoC就是一個用XML來定義生成對象的模式我們看看如果來使用的
數據模型
如下圖所示有三個類Human(人類)是接口Chinese(中國人)是一個子類American(美國人)是另外一個子類
源代碼如下
package chengangspring;
public interface Human {
void eat();
void walk();
}
package chengangspring;
public class Chinese implements Human {
/* (非 Javadoc)
* @see chengangspringHuman#eat()
*/
public void eat() {
Systemoutprintln(中國人對吃很有一套);
}
/* (非 Javadoc)
* @see chengangspringHuman#walk()
*/
public void walk() {
Systemoutprintln(中國人行如飛);
}
}
package chengangspring;
public class American implements Human {
/* (非 Javadoc)
* @see chengangspringHuman#eat()
*/
public void eat() {
Systemoutprintln(美國人主要以面包為主);
}
/* (非 Javadoc)
* @see chengangspringHuman#walk()
*/
public void walk() {
Systemoutprintln(美國人以車代步有四肢退化的趨勢);
}
}
對以上對象采用工廠模式的用法如下
創建一個工廠類Factory如下這個工廠類裡定義了兩個字符串常量所標識不同的人種getHuman方法根據傳入參數的字串來判斷要生成什麼樣的人種
package chengangspring;
public class Factory {
public final static String CHINESE = Chinese;
public final static String AMERICAN = American;
public Human getHuman(String ethnic) {
if (ethnicequals(CHINESE))
return new Chinese();
else if (ethnicequals(AMERICAN))
return new American();
else
throw new IllegalArgumentException(參數(人種)錯誤);
}
}
下面是一個測試的程序使用工廠方法來得到了不同的人種對象並執行相應的方法
package chengangspring;
public class ClientTest {
public static void main(String[] args) {
Human human = null;
human = new Factory()getHuman(FactoryCHINESE);
humaneat();
humanwalk();
human = new Factory()getHuman(FactoryAMERICAN);
humaneat();
humanwalk();
}
}
控制台的打印結果如下
采用Spring的IoC的用法如下
在項目根目錄下創建一個beanxml文件
<?xml version= encoding=UTF?>
<!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beansdtd>
<beans>
<bean id=Chinese class=chengangspringChinese/>
<bean id=American class=chengangspringAmerican/>
</beans>
beanxml的位置如下圖注意不要看花眼把它看成是lib目錄下的了它是在myspring目錄下的
修改ClientTest程序如下
package chengangspring;
import orgntextApplicationContext;
import orgntextsupportFileSystemXmlApplicationContext;
public class ClientTest {
public final static String CHINESE = Chinese;
public final static String AMERICAN = American;
public static void main(String[] args) {
// Human human = null;
// human = new Factory()getHuman(FactoryCHINESE);
// humaneat();
// humanwalk();
// human = new Factory()getHuman(FactoryAMERICAN);
// humaneat();
// humanwalk();
ApplicationContext ctx = new FileSystemXmlApplicationContext(beanxml);
Human human = null;
human = (Human) ctxgetBean(CHINESE);
humaneat();
humanwalk();
human = (Human) ctxgetBean(AMERICAN);
humaneat();
humanwalk();
}
}
從這個程序可以看到ctx就相當於原來的Factory工廠原來的Factory就可以刪除掉了然後又把Factory裡的兩個常量移到了ClientTest類裡整個程序結構基本一樣
再回頭看原來的beanxml文件的這一句
<bean id=Chinese class=chengangspringChinese/>
id就是ctxgetBean的參數值一個字符串class就是一個類(包名+類名)然後在ClientTest類裡獲得Chinese對象就是這麼一句
human = (Human) ctxgetBean(CHINESE)
因為getBean方法返回的是Object類型所以前面要加一個類型轉換
總結
()也許有人說IoC和工廠模式不是一樣的作用嗎用IoC好象還麻煩一點
舉個例子如果用戶需求發生變化要把Chinese類修改一下那麼前一種工廠模式就要更改Factory類的方法並且重新編譯布署而IoC只需要將class屬性改變一下並且由於IoC利用了Java反射機制這些對象是動態生成的這時我們就可以熱插撥Chinese對象(不必把原程序停止下來重新編譯布署)
()也許有人說即然IoC這麼好那麼我把系統所有對象都用IoC方式來生成
注意IoC的靈活性是有代價的設置步驟麻煩生成對象的方式不直觀反射比正常生成對象在效率上慢一點因此使用IoC要看有沒有必要我認為比較通用的判斷方式是用到工廠模式的地方都可以考慮用IoC模式
()在上面的IoC的方式裡還有一些可以變化的地方比如beanxml不一定要放在項目錄下也可以放在其他地方比如chengangspring包裡不過在使用時也要變化一下如下所示
new FileSystemXmlApplicationContext(src/cn/com/chengang/spring/beanxml)
另外beanxml也可以改成其他名字這樣我們在系統中就可以分門別類的設置不同的beanxml
()關於IoC的低侵入性
什麼是低侵入性?如果你用過Struts或EJB就會發現要繼承一些接口或類才能利用它們的框架開發這樣系統就被綁定在StrutsEJB上了對系統的可移植性產生不利的影響如果代碼中很少涉及某一個框架的代碼那麼這個框架就可以稱做是一個低侵入性的框架
Spring的侵入性很低HumenjavaChinesejava等幾個類都不必繼承什麼接口或類但在ClientTest裡還是有一些Spring的影子FileSystemXmlApplicationContext類和ctxgetBean方式等
現在低侵入性似乎也成了判定一個框架的實現技術好壞的標准之一
()關於beanxml的用法
beanxml的用法還有很多其中內容是相當豐富的假設Chinese類裡有一個humenName屬性(姓名)那麼原的beanxml修改如下此後生成Chinese對象時陳剛這個值將自動設置到Chinese類的humenName屬性中而且由於singleton為true這時生成Chinese對象將采用單例模式系統僅存在一個Chinese對象實例
<?xml version= encoding=UTF?>
<!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN
beansdtd>
<beans>
<bean id=Chinese class=chengangspringChinese singleton=true>
<property name=humenName>
<value>陳剛</value>
</property>
</bean>
<bean id=American class=chengangspringAmerican/>
</beans>
關於beanxml的其它用法不再詳細介紹了大家自己拿Spring的文檔一看就明白了
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28795.html