熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

反向控制和面向切面編程在Spring的應用

2013-11-23 20:26:03  來源: Java開源技術 

  摘 要 針對傳統的JEE架構方案常常無法讓人滿意程序過於復雜難以測試和維護成本高根據企業實際需求本文探討了一種輕量級的JEE應用框架Spring 它用更加輕量更加靈活的基礎設施取代了EJB在此對Spring背後的反向控制原理和面向切面編程技術進行了比較深入研究並與傳統實現進行對比顯示了這種框架具有大大降低開發成本可測試等優點

  關鍵詞 Spring反向控制面向切面編程POJO依賴注入

  引言

  在JEE的整個發展歷程中現在正是一個非常時刻從很多方面來說JEE都是一個偉大的成功它成功地在從前沒有標准的地方建立了標准大大提升了企業級軟件的開放程度並且得到了整個行業和開發者的廣泛認可然而JEE在一些方面已經開始捉襟見肘JEE應用開發的成本通常很高JEE應用項目至少和從前的非JEE項目一樣容易失敗——如果不是更容易失敗的話這樣的失敗率高得讓人難以接受在這樣的失敗率之下軟件開發幾乎變成了碰運氣而在JEE遭遇失敗的場景中EJB通常都扮演著重要的角色因此JEE社群不斷地向著更簡單的解決方案更少使用EJB的方向發展[]然而每個應用程序都需要一些基礎設施拒絕使用EJB並不意味著拒絕EJB所采用的基礎設施解決方案那麼如何利用現有的框架來提供這些基礎設施服務呢伴隨著這個問題的提出一個輕量級的JEE解決方案出現了這就是Spring Framework

  Spring是為簡化企業級系統開發而誕生的Spring框架為JEE應用常見的問題提供了簡單有效的解決方案使用Spring你可以用簡單的POJO(Plain Old Java Object)來實現那些以前只有EJB才能實現的功能這樣不只是能簡化服務器端開發任何Java系統開發都能從Spring的簡單可測試和松耦合特征中受益可以簡單的說Spring是一個輕量級的反向控制(IoC)和面向切面編程(AOP)容器框架[]Spring IoC借助於依賴注入設計模式使得開發者不用理會對象自身的生命周期及其關系而且能夠改善開發者對JEE模式的使用Spring AOP借助於Spring實現的攔截器開發者能夠實現以聲明的方式使用企業級服務比如安全性服務事務服務等Spring IoC和 Spring ; AOP組合一起形成了Spring這樣一個有機整體使得構建輕量級的JEE架構成為可能而且事實證明非常有效沒有Spring IoC的Spring AOP是不完善的沒有Spring AOP的Spring IoC是不健壯的本文是以Spring架構的成功的實際商務系統項目為背景闡述了反向控制原理和面向切面的編程技術在Spring框架中的應用同時抽取適量代碼示意具體應用並和傳統開發模式進行對比展示了Spring framework的簡單高效可維護等優點

  Spring IoC 反向控制原理

  反向控制是Spring框架的核心但是反向控制是什麼意思?到底控制的什麼方面被反向了呢?年美國專家Martin Fowler發表了一篇論文《Inversion of Control Containers and the Dependency Injection pattern》闡述了這個問題他總結說是獲得依賴對象的方式反向了根據這個啟示他還為反向控制提出了一個更貼切的名字Dependency Injection(DI 依賴注入)

  通常應用代碼需要告知容器或框架讓它們找到自身所需要的類然後再由應用代碼創建待使用的對象實例因此應用代碼在使用實例之前需要創建對象實例然而IoC模式中創建對象實例的任務交給IoC容器或框架(實現了IoC設計模式的框架也被稱為IoC容器)使得應用代碼只需要直接使用實例這就是IoC相對IoC 而言依賴注入的確更加准確的描述了這種設計理念所謂依賴注入即組件之間的依賴關系由容器在運行期決定形象的來說即由容器動態的將某種依賴關系注入到組件之中

   IoC在Spring中的實現

  任何重要的系統都需要至少兩個相互合作的類來完成業務邏輯通常每個對象都要自己負責得到它的合作(依賴)對象你會發現這樣會導致代碼耦合度高而且難於測試使用IoC對象的依賴都是在對象創建時由負責協調系統中各個對象的外部實體提供的這樣使軟件組件松散連接成為可能下面示意了Spring IoC 應用步驟如下

  ()定義Action接口並為其定義一個execute方法以完成目標邏輯多年前GoF在《Design PatternElements of Reusable ObjectOriented Software》一書中提出Programming to an Interfacenot an implementation的原則這裡首先將業務對象抽象成接口正是為了實施這個原則

  ()類UpperAction實現Action接口在此類中定義一個String型的域message並提供相應的setter和getter方法實現的execute方法如下

public String execute (String str) {
 return (getMessage () + str)toUpperCase () ;
}

  ()編寫Spring配置文件(beanxml)

<beans>
<bean id=TheAction class=netchenspringqsUpperAction
<property name=message
<value>HeLLo</value>
</property>
</bean>
</beans>

  ()測試代碼

public void testQuickStart () {
 ApplicationContext ctx=new
 FileSystemXmlApplicationContext (beanxml);
 Action a= (Action) ctxgetBean (TheAction);
 Systemoutprintln (a execute (Rod Johnson));
}

  上面的測試代碼中我們根據beanxml創建了一個ApplicationContext實例並從此實例中獲取我們所需的Action實現運行測試代碼我們看到控制台輸出

……
HELLO ROD JOHNSON

  仔細觀察一下上面的代碼可以看到

  ()我們的組件並不需要實現框架指定的接口因此可以輕松的將組件從Spring中脫離甚至不需要任何修改這在基於EJB框架實現的應用中是難以想象的

  ()組件間的依賴關系減少極大改善了代碼的可重用性Spring的依賴注入機制可以在運行期為組件配置所需資源而無需在編寫組件代碼時就加以指定從而在相當程度上降低了組件之間的耦合

  Spring給我們帶來了如此這般的好處那麼反過來讓我們試想一下如果不使用Spring框架回到我們傳統的編碼模式情況會是怎樣呢?

  首先我們必須編寫一個配置文件讀取類以實現Message屬性的可配置化

  其次得有一個Factory模式的實現並結合配置文件的讀寫完成Action的動態加載於是我們實現了一個ActionFactory來實現這個功能

public class ActionFactory {
 public static Action getAction (String actionName) {Properties pro = new Properties ();
 try {
  proload (new FileInputStream (configproperties));
  String actionImplName =(String)proget(actionName);
  String actionMessage =(String) proget (actionName+_msg);
  Object obj =ClassforName (actionImplName)newInstance ();
  BeanUtilssetProperty(objmessageactionMessage);
  return (Action) obj;
 } catch (FileNotFoundException e) {
  ……
 }
}

  配置文件則采用properties文件形式如下所示

TheAction=netchenspringqsUpperAction
TheAction_msg=HeLLo

  測試代碼也作相應修改現在不論實現的好壞總之通過上面新增的多行代碼終於實現了類似的功能如果現在有了一個新的需求這樣這個ActionFactory每次都新建一個類的實例顯然這對系統性能不利考慮到我們的兩個Action都是線程安全的修改一下ActionFactory保持系統中只有一個Action實例供其它線程調用另外Action對象創建後需要做一些初始化工作修改一下ActionFactory使其在創建Action實例之後隨即就調用Actioninit方法執行初始化Action的處理這樣就差不多了下面我們來看看另外一個Factory

  ……

  往往這些系統開發中最常見的需求會導致我們的代碼迅速膨脹而Spring IoC的出現則大大緩解了這樣的窘境通過以上實例可以看出Spring IoC為我們提供了如下幾方面的優勢

  ()應用組件不需要在運行時尋找其協作者因此更易於開發和編寫應用

  ()由於借助於IoC容器管理組件的依賴關系使得應用的單元測試和集成測試更利於展開

  ()通常在借助於IoC容器關系業務對象的前提下很少需要使用具體IoC容器提供的API這使得集成現有的遺留應用成為可能

  因此通過使用IoC能夠降低組件之間的耦合度最終能夠提高類的重用性利於測試而且更利於整個產品或系統集成和配置
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28485.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.