? :
          ?
          ? 目前 J2EE 應用中,普遍使用了多層架構。本文提出了基于 J2EE 的輕量級多層架構,即業界比較成熟的 Struts + Spring + Ibatis 框架: Struts 是實現 MVC 最為成熟的框架,在 J2EE 項目中應用廣泛; Spring 可以實現對 Ibatis 的無縫鏈接,適用于業務處理層;在數據持久層中,采用了 Ibatis 這一新的功能強大的 ORM 映射工具。文中討論了輕量級多層架構的應用,并對幾種數據持久層解決方案進行了介紹。在具體的案例中,充分結合 Struts Ibatis J2EE 體系結構過程中的性能,利用了 java 語言的反射機制,并對其中重要組件進行了配置,又從軟件層次結構的角度考慮了此種架構應該注意的問題,包括伸縮性以及可擴展性問題,在實際的項目中取得了很好的效果。

          關鍵詞 :????? 輕量級架構 ;? Struts 框架 ;? Spring ;? Ibatis ; 數據持久層; ORM?

          1? ? J2EE多層應用分析

          1.1? ??????? J2EE層次結構

          J2EE的三層結構在業界是指表示層(Presentation),業務邏輯層(Business logic)以及基礎架構層(Infrastructure)。這樣的劃分當然是經典的,但是在實際項目中,往往會對三層體系結構做一些擴展來滿足項目的需要。一個最常用的擴展就是將三層體系擴展為五層體系,即表示層(Presentation)、控制/中介層(Controller/Mediator) 、領域層(Domain)、 數據持久層(Data Persistence) 和數據源層(Data Source)。它其實是在三層架構中增加了兩個中間層。控制/中介層位于表示層和領域層之間,數據持久層位于領域層和基礎架構層之間。而輕量級架構Struts + Spring + Ibatis可以實現J2EE多層結構,Struts 用于表示層、控制層,Spring 用于業務處理層,而Ibatis 用于數據持久層。

          1.2? ??????? Struts 框架

          Struts是一個基于Sun J2EE平臺的MVC框架,主要是采用ServletJSP技術來實現的。是開發Web應用程序的開放源碼的FrameworkStrutsServletJSP、自定義標簽和信息資源(message resources)整合到一個統一的框架中,開發人員利用其進行開發時不用再自己編碼實現全套MVC模式,極大的節省了時間,Struts包括如下的主要功能:

          ?包含一個controller servlet,能將用戶的請求發送到相應的Action對象。

          ?JSP自由tag庫,并且在controller servlet中提供關聯支持,幫助開發員創建交互式表單應用。

          ?提供了一系列實用對象:XML處理、通過Java reflection APIs自動處理JavaBeans屬性、國際化的提示和消息

          1.3? ??????? Spring 框架

          Spring是一個目前非常活躍的開源項目;它是一個基于IoCInversion of Control)和AOPAspect-Oriented Programming)的,輕量級的,多層j2ee系統的框架,但它不強迫你必須在每一層中必須使用Spring,它模塊化的很好,允許你根據自己的需要選擇使用它的某一個模塊;它實現了很優雅的MVC,對不同的數據訪問技術提供了統一的接口,采用IoC使得可以很容易的實現bean的裝配,提供了簡潔的AOP并據此實現Transcation Managment,等等[ 1 ]

          Spring雖然提供了MVC Web框架的解決方案,但是也能與其他的web框架相結合使用,如strutsWebworkJFS等。Spring也可以與其他持久層結構相結合,如:jdbcHibernateIbatis等,能夠使用AOP的技術提供事務處理等功能?

          1.4? ??????? 數據關系映射Ibatis

          Ibatis 提供了ORM機制,對業務邏輯實現人員而言,面對的是純粹的Java對象, 這一層與通過Hibernate 實現ORM 而言基本一致,而對于具體的數據操作,Hibernate 會自動生成SQL 語句,而Ibatis 則要求開發者編寫具體的SQL 語句。相對Hibernate全自動”ORM機制而言,Ibatis SQL開發的工作量和數據庫移植性上的讓步,為系統設計提供了更大的自由空間。作為全自動”ORM 實現的一種有益補充,Ibatis 的出現顯得別具意義[ 2 ]

          ?

          2? ? J2EE輕量級架構

          2.1? ??????? 架構

          ?

          ?????????????
          ?????????????????????????????????????????????????????????????????????????????????????????????
          ???????????????????????????????????????????????????????????????????????????????????????????????? 圖1? 框架示意圖

          2.2? ??????? View

          在視圖層主要使用Struts結構的技術。

          TagLib

          jsp的前端頁面中使用Struts提供的標簽完成頁面數據邏輯的組織與顯示。如(htmlbeanlogic等)

          國際化的消息處理功能

          jsp頁面中不出現特定語言的字符串描述,將這些統一的字符串信息統一的提取到文件中,通過StrutsBean標簽提取。便于整個系統的語言變更與組織。

          界面組合功能Tiles

          頁面中將使用Struts的技術,統一組織頁面的結構,便于系統改版、維護。

          2.3? ??????? Control

          控制層中依然使用Struts結構。此層將接受、處理View發送的請求,在對信息初步的驗證、處理后,將把此請求委派給后端的業務處理層去處理。等待業務處理完成之后,將把處理結果傳遞給View層進行表現。

          2.4? ??????? 業務處理層

          在該層中使用Service模式,提供給Control層必要的處理方法。

          在接收到Control層的業務處理請求后,按照業務規范、算法對數據進行處理。將處理結果返回給Control層。

          2.5? ??????? 數據訪問層

          本層屬于低級的數據處理層,將完成具體的數據處理工作,如數據的增加,更新,查詢,刪除等。

          本層使用DAOData Access Object)的設計模式[ 3 ],屏蔽多數據庫對上層應用的影響,并使用IbatisORMapping技術,降低數據操作的復雜程度。

          3? ? 數據持久層解決方案

          3.1? ?????????? 數據持久層

          將數據持久單獨作為J2EE體系一個層提出來,表面上是因為數據持久性是企業實際開發中比較棘手的一個方面,數據持久層設計的成功與否往往對項目起著至關重要的影響,單獨將其提出來以便在開發中能夠避免它的設計草率。究其最深刻的內因,則是在對象范例和關系范例這兩大領域之間“阻抗不匹配”。對象范例基于軟件工程的一些原理,例如耦合、聚合和封裝,而關系范例則基于數學原理,特別是集合論的原理。兩種不同的理論基礎導致各自有不同的優缺點。而且,對象范例側重于從包含數據和行為的對象中構建應用程序,而關系范例則主要針對數據的存儲。當為訪問而尋找一種合適的方法時,“阻抗不匹配”就成了主要矛盾:使用對象范例,通過它們的關系來訪問對象,而使用關系范例,則通過復制數據來連接表中的行。這種基本的差異導致兩種范例的結合并不理想,于是有人提出對象數據庫以希望解決這個問題。但是,關系數據庫技術已經發展得相當成熟,占據了數據庫市場90%以上的份額,對象數據庫的普及尚需時日。數據持久層就是要在對象-關系數據庫之間提供一個成功的企業級別的映射解決方案,盡最大可能彌補這兩種范例之間的差異。

          3.2? ?????????? J2EE體系解決方案

          3.2.1? ??? EJB

          CMP (容器管理持久)實體Bean,提供健壯的數據持久性。Bean 容器處理大部分的數據完整性、資源管理和并發性功能,從而使開發人員關注業務邏輯和數據處理,而不是這些低級細節。使用Bean 管理的持久性(Bean Managed PersistenceBMP)實體Bean 時,開發人員編寫持久性代碼而容器確定何時執行該代碼。使用容器管理的持久性?? ( Container Managed PersistenceCMP)實體Bean時,容器生成持久性代碼并管理持久性邏輯[ 4 ]

          3.2.2? ??? JDO

          Java 數據對象 (JDO) 是一個存儲Java對象的規范[ 5 ]。它已經被JCP組織定義成JSR12規范。規范的兩個主要目的是提供數據處理和訪問機制的API以及允許規范的實現作為應用服務器的一部分。Java 數據對象是最新的持久性規范。JDO 提供了面向對象的持久數據存儲。開發人員使用 POJO(無格式普通 Java 對象,Plain Ordinary Java Object)來裝入和存儲持久數據。

          3.2.3? ??? ORM

          ORM 具有自我存儲到關系數據庫的能力,對對象的改變能夠直接得以存儲,而不考慮數據庫存取代碼。這樣,把全部精力集中到對對象和類進行編程,解決業務問題。在整個系統中除了這一個層次,沒有一句數據庫存取代碼。其中,HibernateIbatis作為 ORM中最好的開源工具,受到數量眾多的程序員的擁護。

          4? ? 基于輕量級架構的應用案例分析

          某大型水利信息系統需要使用J2EE 平臺以滿足分布式處理、事務管理和安全的要求,使整個軟件呈現分層的體系結構,支持多種數據庫的擴展,支持多語言界面的調整,支持頁面整體布局的可擴展性調整。封裝業務邏輯,使得在外部條件變化時,將影響盡可能的降低,即采用了基于J2EE的輕量級架構。圖2是信息系統的體系結構,圖3是系統包結構

          ?

          ?????????????????????????????????? 2? 體系結構圖

          ?

          ?

          3? 系統包結構

          ?

          3中箭頭表示軟件包之間的依賴關系。獨立的包會被SpringstrutsIbatis框架結構間接的與其他軟件包關聯。

          4.1? ?????????? 系統剖析

          4.1.1? ??? 包結構描述

          com.water.query.dao:該包內的類將引入Ibatis的重要組件,使系統能夠感知功能操作的接口與接口實現類的關系,這些信息是Ibatis自動映射的前提條件之一。

          com.water.query.dao.sqlmapdao:該包是數據訪問的核心,使用Spring結構的數據層功能引進對Ibatis的支持

          com.water.query.dao.iface :該包規定了所有業務的訪問接口,只有在此包的接口中定義的方法才會被用戶使用。是本系同中所有原子數據操作的定義點。

          Ibatis :該包是由Ibatis數據存儲層結構定義。由支持機構提供支持。

          com.water.query.dao.sqlmapdao.sql :該包定義了所有操作的SQLSequence Query Language)語句,以及SQL語句與具體值對象的映射關系。

          com.water.query.form :該包定義了本系統中用于數據傳輸的類。這些類實例是Web界面層與業務邏輯實現層之間的橋梁,起著傳輸數據的功能。

          com.water.query.service : 該包是本系統引入Spring結構的入口點。通過該入口,系統中其他成員可以通過IoC(依賴倒轉)功能訪問具體業務的Service對象。

          com.water.query.condition :該包內定義了一系列簡單JavaBean,這些JavaBean將攜帶SQL需要的參數穿行于軟件的Control層與Model層之間。

          com.water.log :該包中定義了本系統使用的log組件。

          com.water.query.domain.baseinfo :該包定義了所有基本信息查詢模塊將要使用的數據傳輸類。

          ?

          4.1.2? ??? 控制層

          在視圖層和控制層中采用了Struts框架,在傳統的Struts用法中,我們一般都有幾個Action Bean和相應的form bean ,但在此設計中并不拘泥于Struts的傳統固定用法,這里只用了一個自定義Action類,并且在form bean類的定義上也是創新的。

          非傳統的Struts開發模式,關鍵就在Struts Action類和form bean類上。Struts Action類只有一個:BeanAction,這與傳統的struts編程方式很不同。BeanAction類是一個通用類,利用反射原理[ 6 ],根據URL來決定調用form bean的哪個方法。BeanAction大大簡化了struts的編程模式,降低了對struts的依賴。利用這種模式,我們會很容易的把它移植到新的框架如JSFSpring

          這樣重心就轉移到form bean上了,它已經不是普通意義上的form bean了。它不僅僅有數據和校驗/重置方法,而且已經具有了行為,從這個意義上來說,它更像一個BO(Business Object)Struts-config.xml的配置里有3種映射方式,來告訴BeanAction把控制轉到哪個form bean對象的哪個方法來處理。form bean的這些方法的簽名很簡單,例如:

          public String myActionMethod(){
          ? ????????????????????//..work
          ?????????????????????return "success";

          ?}

          方法的返回值直接就是字符串,對應的是forward的名稱,而不再是ActionForward對象,創建ActionForward對象的任務已經由BeanAction類代勞了。

          ?

          4.1.3? ??? 業務層

          利用Spring Framework BeanFactory機制,采用自定義的工具類(bean工廠類)來加載spring的配置文件,從中可以看出Spring有多靈活,它提供了各種不同的方式來使用其不同的部分/層次,您只需要用你想用的,不需要的部分可以不用。

          具體的來說,創建CustomBeanFactory類,Spring的配置文件applicationContext.xml。以下就是該類的全部代碼,很簡單:

          public final class CustomBeanFactory {

          static XmlBeanFactory factory = null;

          static {

          ???? Resource is = new

          InputStreamResource( CustomBeanFactory.class.

          getResourceAsStream("applicationContext.xml"));

          ???? factory = new XmlBeanFactory(is);?????????????

          }

          public static Object getBean(String beanName){

          ???? return factory.getBean(beanName);

          }

          }

          實際上就是封裝了Spring XMLBeanFactory而已,并且Spring的配置文件只需要加載一次,以后就可以直接用CustomBeanFactory.getBean("someBean")來獲得需要的對象了(例如someBean),而不需要知道具體的類。CustomBeanFactory類用于{耦合1}的解耦。CustomBeanFactory類用于表現層的form bean對象獲得service類的對象。

          4.1.4? ??? 數據持久層的配置

          4.1.4.1? ???? Spring 配置文件

          Spring在設計時就充分考慮到了與Struts的協同工作,并且對Ibatis 有很好的支持,在此輕量級架構中,不需要對Ibatis單獨進行配置,只需對 Spring 進行配置就以足夠。以下就是Spring的配置文件applicationContext.xml

          <?xml version="1.0" encoding="UTF-8"?>

          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

          "http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>

          <bean id="dataSource"

          class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">

          <property name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value>

          </property>

          <property name="url"><value>jdbc:jtds:sqlserver://127.0.0.1:1433/Sample</value>

          </property>

          <property name="username"><value>test</value></property>

          <property name="password"><value>changeit</value></property>

          </bean>

          <bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

          <property name="configLocation"><value>SqlMapConfig.xml</value></property>

          </bean>

          <bean id="transactionManager"

          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

          <property name="dataSource"><ref local="dataSource"/></property>

          </bean>

          <bean id="userDAO" class="net.xiaxin.dao.UserDAO">

          <property name="dataSource"><ref local="dataSource" /></property>

          <property name="sqlMapClient"><ref local="sqlMapClient" /></property>

          </bean>

          </beans>

          可以看到:

          1sqlMapClient節點

          sqlMapClient節點實際上配置了一個sqlMapClient的創建工廠類。

          configLocation屬性配置了ibatis映射文件的名稱。

          2transactionManager節點

          transactionManager采用了Spring中的DataSourceTransactionManager

          3userDAO節點

          對應的,UserDAO需要配置兩個屬性,sqlMapClientDataSource

          sqlMapClient將從指定的DataSource中獲取數據庫連接。

          4.1.4.2? ???? Ibatis映射文件

          sqlMapConfig.xml:

          <sqlMapConfig>

          <sqlMap resource="net/xiaxin/dao/entity/user.xml"/>

          </sqlMapConfig>

          user.xml為:

          <sqlMap namespace="User">

          <typeAlias alias="user" type="net.xiaxin.dao.entity.User" />

          <insert id="insertUser" parameterClass="user">

          INSERT INTO users ( username, password) VALUES ( #username#,

          #password# )

          </insert>

          </sqlMap>

          UserDAO.java

          public class UserDAO extends SqlMapClientDaoSupport implements

          IUserDAO {

          public void insertUser(User user) {

          getSqlMapClientTemplate().update("insertUser", user);

          }

          }

          SqlMapClientDaoSupportSpring中面向ibatis的輔助類,它負責調度DataSource

          SqlMapClientTemplate完成ibatis操作,而DAO則通過對此類進行擴展獲得上述功能。上面配置文件中針對UserDAO的屬性設置部分,其中的屬性也是繼承自于這個基類。SqlMapClientTemplate對傳統SqlMapClient調用模式進行了封裝,簡化了上層訪問代碼。

          5? ? 總結

          從軟件層次結構的角度來說,軟件的框架要具有較高的伸縮性和可擴展性,本文所討論的J2EE輕量級架構,由于它采用了Struts框架,因而它的模塊化設計得到了很好的應用,層次非常清晰,具有很好的可復用度,但是,同時,此架構存在可伸縮性問題,架構中明顯存在可伸縮性問題的設計是Action。控制器ActionServlet 對每個Action 類只創建一個實例,所有對該Action 類的請求都用這個實例進行處理,因此,它是無狀態的、多線程共享的。這意味著Action 實例的數量是一個常數,不能隨工作量增加而增加。此外,反射的利用是對架構擴展的一個有益嘗試,雖然提供了非常好的應用開發模式,但是它還非常新,一直在發展中。數據持久層中,Ibatis的應用給人一種耳目一新的感覺,但它也存在著一些不足之處,例如相對于Hibernate Ibatis不能直接生成sql語句,需要人工編寫。

          輕量級架構結合StrutsSpringIbatis ,充分發揮了三者的優點, 基于輕量級框架的J2EE 架構開發簡潔、結構清晰,有很好的可擴展性和可維護性,非常適于面向對象的設計與開發。

          ?

          參考文獻(References

          ?[1]?? Expert One-on-One J2EE Design and Development? (美)Rod ohnson,Juergen Hoeller

          機械工業出版社 2005-8-1

          [2] ??What is iBATIS?? http://ibatis.apache.org/? 2005

          [3] ?iBatis DAO? http://www.onjava.com/pub/a/onjava/2005/08/10/ibatisdao.html? 2005

          [4] ?Roman E. Mastering EJB (2nd Edition). 北京: 機械工業出版社,? 2003-01

          [5]? JDO:SunJDOSpecification[EB/OL].

          http://www.jcp.org/aboutJava/communityprocess/first/jsr012/index.html , 2003

          [6] Java編程思想(第2版)(美)Bruce Eckel機械工業出版社2002-9-1

          Feedback

          # re: 基于J2EE輕量級架構的多層應用的研究  回復  更多評論   

          2006-06-16 10:43 by
          為什么不給個完整的簡單的例子
          學習一下

          # re: 基于J2EE輕量級架構的多層應用的研究  回復  更多評論   

          2006-06-16 11:42 by 寒晴天
          哈哈,好文章

          # re: 基于J2EE輕量級架構的多層應用的研究  回復  更多評論   

          2006-06-16 13:24 by google
          路過

          # re: 基于J2EE輕量級架構的多層應用的研究  回復  更多評論   

          2007-06-18 16:27 by ploow
          FrameCountry是采用.Net的開發平臺,專注于數據庫訪問層功能的架構系統,為用戶提供便捷、規范、強大的功能,提升開發效率。

          FrameCountry特點
          1. 便捷開發:封裝、整合數據庫操作方式,讓開發人員擺脫數據庫的約束;
          2. 規范開發:依據多層設計原理,明晰人員分工,提高程序可讀性;
          3. 記錄運行情況:開發人員依據記錄了解系統詳情,方便調試排錯;
          4. 多樣數據庫連接:實現多種數據庫連接方式,對開發人員透明化數據庫連接,使其只關注上層程序,同時降低數據庫轉換、升級工作量,目前實現Access2000、SQLServer2000兩種數據庫,日后逐步增加關系型數據庫連接配置;
          5. 整合有效函數:對開發中其它的有用的、常用的函數進行整理,簡單調用實現;

          訪問http://blog.csdn.net/lizheng82

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          posts - 4, comments - 8, trackbacks - 0, articles - 0

          Copyright © 曹青松

          主站蜘蛛池模板: 象州县| 密山市| 新郑市| 枣阳市| 永州市| 崇阳县| 阜新| 理塘县| 唐河县| 乌苏市| 维西| 山东| 新野县| 信阳市| 周宁县| 安吉县| 齐河县| 根河市| 榆中县| 拜泉县| 共和县| 邹平县| 长武县| 石景山区| 谢通门县| 伊春市| 大余县| 宜宾市| 察隅县| 海淀区| 河津市| 山西省| 固镇县| 德江县| 名山县| 沂源县| 洪洞县| 体育| 贵州省| 巨鹿县| 微博|