Struts+Spring+Hibernate+Aglets集成架構

     目前比較流行MVC架構有Struts、Spring、WebWork、JSF,

Struts是一個基於Sun J2EE平臺的MVC框架,主要是採用Servlet和JSP技術來實現的。由於Struts能充分滿足應用開發的需求,簡單易用,敏捷迅速,在過去一直頗受關注。

Spring提供了管理業務對象的一致方法並且鼓勵了注入對接口編程而不是對類編程的良好習慣。Spring的架構基礎是基於使用JavaBean屬性的Inversion of Control容器。Spring提供了唯一的數據訪問抽象,包括簡單和有效率的JDBC框架,極大的改進了效率並且減少了可能的錯誤。Spring的數據訪問架構還集成了Hibernate和其他O/R mapping解決方案。WebWork、JSF在此就不介紹,有興趣可以到google搜索相關的文章。 目前比較流行的O/R mapping框架有Hibernate、IBatis,Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,使得我們可以隨心所欲的使用對象編程思維來操縱數據庫。 如何將Struts、Spring、Hibernate集成一起使用,並充分使用他們各自長處呢?接下來我對Struts+Spring+Hibernate集成的分層作分析和如何實現集成

     服務器端web應用程序共分五層:表示層(view)、控制層(controller)、業務層(business)、DAO層(Data Access Object)、持久層(persistence)+RMI。每個層在處理程序上都有一項明確的責任,不應該在功能上與其它層混合,並且每個層要與其它層分開的,所以需要設計他們之間通信接口。從介紹各個層開始,討論一下這些層擔當的任務和各層的功能以及它們的相互關係。

 一、 表示層:視圖是用戶看到並與之交互的界面,視圖向用戶顯示相關的數據,並能接收用戶的輸入數據,但不能進行任何實際的業務處理。視圖可以向業務層查詢業務狀態,但不能改變業務層,視圖還可以接受模型發出的數據更新事件,從而對用戶界面進行同步更新。視圖其實就是一組JSP文件,在這些JSP文件中沒有業務邏輯,也沒有業務層信息,只有標籤,這些標籤可以是標準的JSP標籤或客戶化標籤,如Struts標籤庫中的標籤。由架構圖可知,把Struts框架中的ActionForm Bean分到了表示層中,ActionForm Bean也是一種JavaBean,除了具有一些JavaBean的常規方法,還包含一些特殊的方法,用於驗證HTML表單數據以及將其屬性重新設置爲默認值。Struts框架利用ActionForm Bean來進行視圖和控制器之間表單數據之間表單數據的傳遞,Struts框架把用戶輸入的表單數據保存在ActionForm Bean中,把它傳遞給控制器Action,Action可以對ActionForm Bean中數據進行修改,JSP文件使用Struts標籤讀取修改後的ActionForm Bean中的信息,重新設置HTML表單。

 二、 控制層:控制層中的控制器Action接受用戶的輸入並調用業務層的業務方法和表示層的組件去完成用戶的需求。當Web用戶單擊Web頁面中的提交按鈕來發送HTML表單時,控制器接收請求並調用相應的業務層方法去處理請求,然後調用相應的視圖來顯示業務層返回的數據。 Struts中的控制器由ActionServlet類和Action類來實現,ActionServlet主要負責接收HTTP請求信息,根據配置文件struts-config.xml的配置信息,把請求轉發給適當的Action對象。如果該Action對象不存在,ActionServlet會先創建這個Action對象,Action充當用戶請求和業務邏輯處理之間的適配器,其功能是將請求與業務邏輯分開,Action根據用戶請求調用相關的業務邏輯組件,業務邏輯由Spring的IoC、AOP、DAO、ORM來完成,Action類側重於控制應用程序的流程,而不是實現應用程序的邏輯。爲了使用Action中使用到Spring受管理JavaBean、IoC、AOP來調用Spring的業務邏輯、事務管理、安全性服務。Spring對Struts提供了這種集成服務,通過org.springframework.web.struts.DelegatingRequestProcessor類充當Action的代理,將Struts Action配置在Spring ApplicationContext中,而且Action不必繼承於ActionSuport,每次客戶請求Struts Action時,DelegatingRequestProcessor將充當代理的作用,即通過它將Action請求轉發給Spring IoC容器進行處理。通過這樣的方式,Spring 獲得了對Action 實例的管理權,它將對Action進行調度,併爲Struts提供所需的Action實例。既然Action已經由Spring全權接管,那麼就可以將此Action看作是Spring中的一個Bean,它可享受Spring提供的所有服務(依賴注入、實例管理、事務管理等)。 

三、 業務層:業務層應該和表示層以及控制層之間保持獨立,在本集成分層框架中,位於上層的表示層和控制層依賴於下層的業務層的實現,而下層業務層不應該依賴於上層的表示層和控制器的實現。業務層提供了處理應用程序的業務邏輯和業務校驗,如驗證用戶登陸系統的密碼是否正確;提供了管理事務,允許與其它層相互作用的接口,如使用Spring的管理事務Bean和DAO層的DAO接口類以及給Action提供業務接口。業務層還提供了管理業務層級別的對象的依賴、管理程序的執行(從業務層到持久層)等。 

四、DAO層: DAO提供了訪問關係型數據庫所需要的所有操作的接口,其中包括創建數據庫、定義表、字段和索引,建立表間的關係,更新和查詢數據庫等,DAO將底層數據(Hibernate持久對象)訪問操作和業務層(business層)邏輯分離開,對業務層(business層)提供面向對象的數據訪問接口。而業務層(business層)調用DAO接口實現各種業務方法,如驗證用戶密碼是否正確業務方法,並向控制層(Action類)提供調用業務方法的接口。 

五、持久層:由集成圖可看出,Web應用的另一個末端是持久層Hibernate,Hibernate是一個ORM工具,沒有Hibernate時,通常使用JDBC來連接數據庫,並利用連接池來改善性能,利用事務服務來保證可靠性,還會利用JNDI來傳遞數據源,配合SQL語言來完成數據庫的查詢操作。但Hibernate可以複雜性的JDBC過程以對象系統映射的方式對開發者透明,將需要經驗和技巧的設計部分封裝在PO對象和XML映射文件的配置中。使用了Hibernate應用程序就不需發直接面對JDBC代碼,由PO對象和Hibernate的API來取代。Hibernate利用hibernate.cfg.xml或hibernate.properties文件來配置Hibernate所使用的包括數據庫和連接池等在內的資源,Hibernate利用*.hbm.xml來描述POJO和數據庫資源的映射關係。

 六、RMI Spring提供類用於集成各種遠程訪問技術,對遠程訪問的支持可以降低在用POJO實現支持遠程訪問業務時的開發難度。Spring提供了對遠程方法調用(RMI)的支持,藉助於Spring提供的RmiProxyFactoryBean和RmiServiceExporter可以開發RMI應用。RMI服務器集成了Aglets的運行環境AgletContext,並實現了Agent相關業務方法,由業務層通過RMI的業務接口DAO來完成Agent相關的業務。 

七、集成實現 

7.1 Spring集成Struts Struts是基於MVC的,它實現了Model2模型的Web應用框架,Struts框架的核心作用其提供的靈活的控制層,它是基於Java Servlet、JavaBean、ResourceBundle、XML等技術構建的。 Spring對Struts提供了兩種集成方式: 

一是通過org.springframework.web.context.ContxtLoaderServlet來初始化Spring ApplicationContext的,Spring爲了集成Struts,專門提供了org.springframework.web.struts包,爲了初始化Spring ApplicationContext,需要在struts-config.xml中配置如下內容: 

二是通過org.springframework.web.struts.DelegatingRequestProcessor類充當Action的代理,將Struts Action配置在Spring ApplicationContext中,而且Action不必繼承於ActionSuport,每次客戶請求Struts Action時,DelegatingRequestProcessor將充當代理的作用,即通過它將Action請求轉發給Spring IoC容器進行處理。Action將可以使用到Spring IoC容器的功能。具體使用步驟如下: 在struts-config.xml中配置DelegatingRequestProcessor。 其次在Spring配置文件applicationContext.xml中定義名字”/customerRegister.do”的受管JavaBean。

 如此一來,Struts 在運行期加載的實際上是DelegatingActionProxy , 而DelegatingActionProxy則實現了針對實際Action的調用代理,Struts最終調用的將是由Spring管理的Action實例。通過這樣的方式,Spring 獲得了對Action 實例的管理權,它將對Action進行調度,併爲Struts提供所需的Action實例。既然Action已經由Spring全權接管,那麼就可以將此Action看作是Spring中的一個Bean,它可享受Spring提供的所有服務(依賴注入、實例管理、事務管理等)。

 7.2 Spring集成Hibernate Hibernate提供了O/R Mapping功能,通過XML配置文件能夠將對象映射到RDBMS,開發Hibernate需要如下內容: Hibernate配置文件。一般可以通過兩種方式進行。一是提供hibernate.cfg.xml文件,用於創建Hibernate SessionFactory。二是提供hibernate.properties文件。 Hibernate映射文件。如Vip.hbm.xml POJO類源文件。如com.hour41.vo.user.Vip.java。 Spring對Hibernate的集成提供了定義Hibernate資源、對Hibernate資源的依賴注入。定義Hibernate資源:可以通過在Spring配置文件中定義sessionFactory是給出Hibernate映射文件的定義。如本系統的sessionFactory定義如下: <:property name="driverClassName">com.mysql.jdbc.Driver <:property name="url">jdbc:mysql://192.168.1.200:3306/hour41 <:property name="username">root <:property name="password">123456 <:property name="dataSource"><:property name="mappingResources">com/hour41/vo/common/City.hbm.xml <:property name="hibernateProperties">org.hibernate.dialect.MySQLDialect true Spring DAO Hibernate抽象提供了HibernateTemplate,HibernateTemplate充分利用了Spring IoC特徵,從而實現了對Hibernate資源的依賴注入。如果應用只是用Spring IoC,則只需要在Spring配置文件中爲它提供sessionFactory。如上配置文件。

 7.3 Spring對Aglets集成由於通過遠程RMI服務器集成Aglet的運行環境AgletContext,所以我們只要將RMI服務集成到Spring中,並將RMI服務接口IAgentDAO作爲Spring中的一個Bean,它可享受Spring提供的所有服務(依賴注入、實例管理、事務管理等)。 Spring提供類用於集成各種遠程訪問技術,對遠程訪問的支持可以降低在用POJO實現支持遠程訪問業務時的開發難度。Spring提供了對遠程方法調用(RMI)的支持,藉助於Spring提供的RmiProxyFactoryBean和RmiServiceExporter可以開發RMI應用。Spring同時支持兩種方式開發RMI應用,一是基於傳統的方式,即同java.rmi.Remote和java.rmi.RemoteExcpetion配合使用;二是基於RMI Invoker,通過使用RmiProxyFactoryBean和RmiServiceExporter。本系統將採用RMI Invoker方式,下面介紹開發步驟: 通常,開發RMI應用的步驟如下: 開發繼承於java.rmi.Remote業務接口類。需要在每個業務方法的簽名中拋出java.rmi..RemoteException。 實現業務接口類。在實現業務接口類過程中,除了需要實現業務接口類外,還需要繼承於java.rmi.server.UnicastRemoteObject。 開發RMI服務器代碼,將遠程服務註冊到RMI註冊器(registry)中。需要藉助於Naming提供的綁定操作,從而供客戶調用。 開發客戶端代碼。藉助於Naming.lookup()方法能夠查找到所需的遠程服務,並且調用它。藉助於rmic實用工具,編譯存根(stub)。 啓動RMI註冊器,即通過start rmiregistry命令行完成RMI註冊器的啓動。 啓動RMI服務器代碼,從而能夠導出遠程服務,註冊到RMI註冊器中。 運行客戶端應用程序。 由上可以看出,開發RMI應用服務的步驟比較煩瑣。藉助於Spring提供的代理工廠JavaBean,依據RMI開發模型開發RMI應用變得相當簡單,下面介紹RMI Invoker方式開發RMI服務:開發IAgentDAO接口,供導出遠程服務使用。IAgentDAO業務接口中的方法並沒有拋出java.rmi.RemoteException異常,還有IAgentDAO也沒有繼承於java.remote.Remote,Spring藉助於代理工廠JavaBean和RMIServerExporter能夠消除業務接口中的這方面需要。接口代碼如下: package com.hour41.spring.rmi.dao; public interface IAgentDAO { public void createAglet(String agletPath); } 實現IAgentDAO接口。根據IAgentDAO.java接口,完成AgentDAO類的開發: package com. hour41.spring.rmi.dao; import com.ibm.aglet.*; import java.net.*; public class AgentDAO implements IAgentDAO { private static AgletContext cxt = null; public AgentDAO(String port, String userName, String password) { cxt = AgentContext.getAgletContext(port, userName, password); } public void createAglet(String agletPath) { try { URL codebase = new URL("File:/" + agletPath); cxt.createAglet(codebase, "aglettest.MainAglet", null); } catch (Exception e) { e.printStackTrace(); } } } 通過上述過程,整個RMI遠程服務的Java代碼開發完成。Spring能夠將任何POJO導出成RMI遠程服務,同RMI編程模型相關的內容都是通過Spring配置文件完成。配置RMI服務端使用的Spring配置文件,即appcontextrmiserver.xml。 

4000

dengddq

820424


LogAgentDAO <:property name="serviceInterface">com. hour41.spring.rmi.dao.IAgentDAO

1200 藉助於RmiServiceExporter,不用直接使用rmic生成存根、不用通過程序手工將遠程服務註冊到RMI註冊器中。RmiServiceExporter爲開發完成了這些繁瑣的工作。通過serviceName屬性能夠指定RMI服務名,即對應於Naming綁定操作中的邏輯服務名;通過service屬性能夠指定提供業務邏輯的實現類,即AgentDAO;通過serviceInterface屬性能夠指定AgentDAO服務實現的接口,即客戶將通過該接口同RMI遠程程序(AgentDAO)進行交互;通過registryPort屬性能夠修改默認RMI註冊端口。 配置使用上述RMI遠程服務,即供客戶使用的Spring配置文件(appcontextrmiclient.xml):

rmi://localhost:1200/LogAgentDAO com. hour41.spring.rmi.dao.IAgentDAO 由上配置文件可看到RmiProxyFactoryBean是工廠JavaBean,它是RMI遠程服務代理,並能夠捕捉到RemoteException,並將RemoteException轉化爲未受查的異常。通過serviceUrl屬性能夠指定RMI的URL;通過serviceInterface屬性能夠指定業務接口。 開發提供RMI客戶應用,即LogAgentDAORmiClient.java package com. hour41.spring.rmi.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class LogAgentRmiClient { protected static final Log log = LogFactory.getLog (LogAgentRmiClient.class); public static void main(String[] args) { //初始化appcontextrmiclient.xml Resource cresource = new ClassPathResource ("appcontextrmiclient.xml"); BeanFactory cfactory = new XmlBeanFactory(cresource); //獲得RMI服務 IAgentDAO clientLog = (IAgentDAO) cfactory.getBean ("logAgentDAO"); //調用RMI服務 clientLog.createAglet("d:/test"); } } 通過“logAgentDAO”邏輯名能夠獲得RMI服務,最終調用到RMI服務提供的實例方法createAglet()。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章