<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    一葉笑天
    雄關(guān)漫道真如鐵, 而今邁步從頭越。 從頭越, 蒼山如海, 殘陽如血。
    posts - 73,comments - 7,trackbacks - 0

    原文位置:http://www-128.ibm.com/developerworks/cn/java/j-sr2.html

    使用 Spring 更好地處理 Struts 動作

    三種整合 Struts 應(yīng)用程序與 Spring 的方式

    級別: 中級

    George Franciscus (george.franciscus@nexcel.ca), 負(fù)責(zé)人, Nexcel

    2005 年 10 月 11 日

    Struts Recipes 的合著者 George Franciscus 將介紹另一個重大的 Struts 整合竅門 —— 這次是將 Struts 應(yīng)用程序?qū)?Spring 框架。請跟隨 George,他將向您展示如何改變 Struts 動作,使得管理 Struts 動作就像管理 Spring beans 那樣。結(jié)果是一個增強(qiáng)的 web 框架,這個框架可以方便地利用 Spring AOP 的優(yōu)勢。

    您肯定已經(jīng)聽說過控制反轉(zhuǎn) (IOC) 設(shè)計(jì)模式,因?yàn)楹荛L一段時間以來一直在流傳關(guān)于它的信息。如果您在任何功能中使用過 Spring 框架,那么您就知道其原理的作用。在本文中,我利用這一原理把一個 Struts 應(yīng)用程序注入 Spring 框架,您將親身體會到 IOC 模式的強(qiáng)大。

    將一個 Struts 應(yīng)用程序整合進(jìn) Spring 框架具有多方面的優(yōu)點(diǎn)。首先,Spring 是為解決一些關(guān)于 JEE 的真實(shí)世界問題而設(shè)計(jì)的,比如復(fù)雜性、低性能和可測試性,等等。第二,Spring 框架包含一個 AOP 實(shí)現(xiàn),允許您將面向方面技術(shù)應(yīng)用于面向?qū)ο蟮拇a。第三,一些人可能會說 Spring 框架只有處理 Struts 比 Struts 處理自己好。但是這是觀點(diǎn)問題,我演示三種將 Struts 應(yīng)用程序整合到 Spring 框架的方法后,具體由您自己決定使用哪一種。

    我所演示的方法都是執(zhí)行起來相對簡單的,但是它們卻具有明顯不同的優(yōu)點(diǎn)。我為每一種方法創(chuàng)建了一個獨(dú)立而可用的例子,這樣您就可以完全理解每種方法。請參閱 下載 部分獲得完整例子源代碼。請參閱 參考資料,下載 Struts MVC 和 Spring 框架。

    為什么 Spring 這么了不起?

    Spring 的創(chuàng)立者 Rod Johnson 以一種批判的眼光看待 Java™ 企業(yè)軟件開發(fā),并且提議很多企業(yè)難題都能夠通過戰(zhàn)略地使用 IOC 模式(也稱作依賴注入)來解決。當(dāng) Rod 和一個具有奉獻(xiàn)精神的開放源碼開發(fā)者團(tuán)隊(duì)將這個理論應(yīng)用于實(shí)踐時,結(jié)果就產(chǎn)生了 Spring 框架。簡言之,Spring 是一個輕型的容器,利用它可以使用一個外部 XML 配置文件方便地將對象連接在一起。每個對象都可以通過顯示一個 JavaBean 屬性收到一個到依賴對象的引用,留給您的簡單任務(wù)就只是在一個 XML 配置文件中把它們連接好。

    IOC 和 Spring

    IOC 是一種使應(yīng)用程序邏輯外在化的設(shè)計(jì)模式,所以它是被注入而不是被寫入客戶機(jī)代碼中。將 IOC 與接口編程應(yīng)用結(jié)合,就像 Spring 框架那樣,產(chǎn)生了一種架構(gòu),這種架構(gòu)能夠減少客戶機(jī)對特定實(shí)現(xiàn)邏輯的依賴。請參閱 參考資料 了解更多關(guān)于 IOC 和 Spring 的信息。

    依賴注入是一個強(qiáng)大的特性,但是 Spring 框架能夠提供更多特性。Spring 支持可插拔的事務(wù)管理器,可以給您的事務(wù)處理提供更廣泛的選擇范圍。它集成了領(lǐng)先的持久性框架,并且提供一個一致的異常層次結(jié)構(gòu)。Spring 還提供了一種使用面向方面代碼代替正常的面向?qū)ο蟠a的簡單機(jī)制。

    Spring AOP 允許您使用攔截器 在一個或多個執(zhí)行點(diǎn)上攔截應(yīng)用程序邏輯。加強(qiáng)應(yīng)用程序在攔截器中的日志記錄邏輯會產(chǎn)生一個更可讀的、實(shí)用的代碼基礎(chǔ),所以攔截器廣泛用于日志記錄。您很快就會看到,為了處理橫切關(guān)注點(diǎn),Spring AOP 發(fā)布了它自己的攔截器,您也可以編寫您自己的攔截器。





    回頁首


    整合 Struts 和 Spring

    與 Struts 相似,Spring 可以作為一個 MVC 實(shí)現(xiàn)。這兩種框架都具有自己的優(yōu)點(diǎn)和缺點(diǎn),盡管大部分人同意 Struts 在 MVC 方面仍然是最好的。很多開發(fā)團(tuán)隊(duì)已經(jīng)學(xué)會在時間緊迫的時候利用 Struts 作為構(gòu)造高品質(zhì)軟件的基礎(chǔ)。Struts 具有如此大的推動力,以至于開發(fā)團(tuán)隊(duì)寧愿整合 Spring 框架的特性,而不愿意轉(zhuǎn)換成 Spring MVC。沒必要進(jìn)行轉(zhuǎn)換對您來說是一個好消息。Spring 架構(gòu)允許您將 Struts 作為 Web 框架連接到基于 Spring 的業(yè)務(wù)和持久層。最后的結(jié)果就是現(xiàn)在一切條件都具備了。

    在接下來的小竅門中,您將會了解到三種將 Struts MVC 整合到 Spring 框架的方法。我將揭示每種方法的缺陷并且對比它們的優(yōu)點(diǎn)。 一旦您了解到所有三種方法的作用,我將會向您展示一個令人興奮的應(yīng)用程序,這個程序使用的是這三種方法中我最喜歡的一種。





    回頁首


    三個小竅門

    接下來的每種整合技術(shù)(或者竅門)都有自己的優(yōu)點(diǎn)和特點(diǎn)。我偏愛其中的一種,但是我知道這三種都能夠加深您對 Struts 和 Spring 的理解。在處理各種不同情況的時候,這將給您提供一個廣闊的選擇范圍。方法如下:

    • 使用 Spring 的 ActionSupport 類整合 Structs
    • 使用 Spring 的 DelegatingRequestProcessor 覆蓋 Struts 的 RequestProcessor
    • 將 Struts Action 管理委托給 Spring 框架

    裝載應(yīng)用程序環(huán)境

    無論您使用哪種技術(shù),都需要使用 Spring 的 ContextLoaderPlugin 為 Struts 的 ActionServlet 裝載 Spring 應(yīng)用程序環(huán)境。就像添加任何其他插件一樣,簡單地向您的 struts-config.xml 文件添加該插件,如下所示:

    <plug-in className=
                            "org.springframework.web.struts.ContextLoaderPlugIn">
                            <set-property property=
                            "contextConfigLocation" value="/WEB-INF/beans.xml"/>
                            </plug-in>
                            

    前面已經(jīng)提到過,在 下載 部分,您能夠找到這三個完全可使用的例子的完整源代碼。每個例子都為一個書籍搜索應(yīng)用程序提供一種不同的 Struts 和 Spring 的整合方法。您可以在這里看到例子的要點(diǎn),但是您也可以下載應(yīng)用程序以查看所有的細(xì)節(jié)。





    回頁首


    竅門 1. 使用 Spring 的 ActionSupport

    手動創(chuàng)建一個 Spring 環(huán)境是一種整合 Struts 和 Spring 的最直觀的方式。為了使它變得更簡單,Spring 提供了一些幫助。為了方便地獲得 Spring 環(huán)境,org.springframework.web.struts.ActionSupport 類提供了一個 getWebApplicationContext() 方法。您所做的只是從 Spring 的 ActionSupport 而不是 Struts Action 類擴(kuò)展您的動作,如清單 1 所示:


    清單 1. 使用 ActionSupport 整合 Struts
    package ca.nexcel.books.actions;
                            import java.io.IOException;
                            import javax.servlet.ServletException;
                            import javax.servlet.http.HttpServletRequest;
                            import javax.servlet.http.HttpServletResponse;
                            import org.apache.struts.action.ActionError;
                            import org.apache.struts.action.ActionErrors;
                            import org.apache.struts.action.ActionForm;
                            import org.apache.struts.action.ActionForward;
                            import org.apache.struts.action.ActionMapping;
                            import org.apache.struts.action.DynaActionForm;
                            import org.springframework.context.ApplicationContext;
                            import org.springframework.web.struts.ActionSupport;
                            import ca.nexcel.books.beans.Book;
                            import ca.nexcel.books.business.BookService;
                            public class SearchSubmit extends ActionSupport {   |(1)
                            public ActionForward execute(
                            ActionMapping mapping,
                            ActionForm form,
                            HttpServletRequest request,
                            HttpServletResponse response)
                            throws IOException, ServletException {
                            DynaActionForm searchForm = (DynaActionForm) form;
                            String isbn = (String) searchForm.get("isbn");
                            //the old fashion way
                            //BookService bookService = new BookServiceImpl();
                            ApplicationContext ctx =
                            getWebApplicationContext();    |(2)
                            BookService bookService =
                            (BookService) ctx.getBean("bookService");   |(3)
                            Book book = bookService.read(isbn.trim());
                            if (null == book) {
                            ActionErrors errors = new ActionErrors();
                            errors.add(ActionErrors.GLOBAL_ERROR,new ActionError
                            ("message.notfound"));
                            saveErrors(request, errors);
                            return mapping.findForward("failure") ;
                            }
                            request.setAttribute("book", book);
                            return mapping.findForward("success");
                            }
                            }
                            

    讓我們快速思考一下這里到底發(fā)生了什么。在 (1) 處,我通過從 Spring 的 ActionSupport 類而不是 Struts 的 Action 類進(jìn)行擴(kuò)展,創(chuàng)建了一個新的 Action。在 (2) 處,我使用 getWebApplicationContext() 方法獲得一個 ApplicationContext。為了獲得業(yè)務(wù)服務(wù),我使用在 (2) 處獲得的環(huán)境在 (3) 處查找一個 Spring bean。

    這種技術(shù)很簡單并且易于理解。不幸的是,它將 Struts 動作與 Spring 框架耦合在一起。如果您想替換掉 Spring,那么您必須重寫代碼。并且,由于 Struts 動作不在 Spring 的控制之下,所以它不能獲得 Spring AOP 的優(yōu)勢。當(dāng)使用多重獨(dú)立的 Spring 環(huán)境時,這種技術(shù)可能有用,但是在大多數(shù)情況下,這種方法不如另外兩種方法合適。





    回頁首


    竅門 2. 覆蓋 RequestProcessor

    將 Spring 從 Struts 動作中分離是一個更巧妙的設(shè)計(jì)選擇。分離的一種方法是使用 org.springframework.web.struts.DelegatingRequestProcessor 類來覆蓋 Struts 的 RequestProcessor 處理程序,如清單 2 所示:


    清單 2. 通過 Spring 的 DelegatingRequestProcessor 進(jìn)行整合
    <?xml version="1.0" encoding="ISO-8859-1" ?>
                            <!DOCTYPE struts-config PUBLIC
                            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
                            "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
                            <struts-config>
                            <form-beans>
                            <form-bean name="searchForm"
                            type="org.apache.struts.validator.DynaValidatorForm">
                            <form-property name="isbn"    type="java.lang.String"/>
                            </form-bean>
                            </form-beans>
                            <global-forwards type="org.apache.struts.action.ActionForward">
                            <forward   name="welcome"                path="/welcome.do"/>
                            <forward   name="searchEntry"            path="/searchEntry.do"/>
                            <forward   name="searchSubmit"           path="/searchSubmit.do"/>
                            </global-forwards>
                            <action-mappings>
                            <action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
                            <action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
                            <action    path="/searchSubmit"
                            type="ca.nexcel.books.actions.SearchSubmit"
                            input="/searchEntry.do"
                            validate="true"
                            name="searchForm">
                            <forward name="success" path="/WEB-INF/pages/detail.jsp"/>
                            <forward name="failure" path="/WEB-INF/pages/search.jsp"/>
                            </action>
                            </action-mappings>
                            <message-resources parameter="ApplicationResources"/>
                            <controller processorClass="org.springframework.web.struts.
                            DelegatingRequestProcessor"/> |(1)
                            <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
                            <set-property property="pathnames"
                            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
                            </plug-in>
                            <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
                            <set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/>
                            </plug-in>
                            </struts-config>
                            

    我利用了 <controller> 標(biāo)記來用 DelegatingRequestProcessor 覆蓋默認(rèn)的 Struts RequestProcessor。下一步是在我的 Spring 配置文件中注冊該動作,如清單 3 所示:


    清單 3. 在 Spring 配置文件中注冊一個動作
    <?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="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
                            <bean name="/searchSubmit"
                            class="ca.nexcel.books.actions.SearchSubmit"> |(1)
                            <property name="bookService">
                            <ref bean="bookService"/>
                            </property>
                            </bean>
                            </beans>
                            

    注意:在 (1) 處,我使用名稱屬性注冊了一個 bean,以匹配 struts-config 動作映射名稱。SearchSubmit 動作揭示了一個 JavaBean 屬性,允許 Spring 在運(yùn)行時填充屬性,如清單 4 所示:


    清單 4. 具有 JavaBean 屬性的 Struts 動作
    package ca.nexcel.books.actions;
                            import java.io.IOException;
                            import javax.servlet.ServletException;
                            import javax.servlet.http.HttpServletRequest;
                            import javax.servlet.http.HttpServletResponse;
                            import org.apache.struts.action.Action;
                            import org.apache.struts.action.ActionError;
                            import org.apache.struts.action.ActionErrors;
                            import org.apache.struts.action.ActionForm;
                            import org.apache.struts.action.ActionForward;
                            import org.apache.struts.action.ActionMapping;
                            import org.apache.struts.action.DynaActionForm;
                            import ca.nexcel.books.beans.Book;
                            import ca.nexcel.books.business.BookService;
                            public class SearchSubmit extends Action {
                            private BookService bookService;
                            public BookService getBookService() {
                            return bookService;
                            }
                            public void setBookService(BookService bookService) { | (1)
                            this.bookService = bookService;
                            }
                            public ActionForward execute(
                            ActionMapping mapping,
                            ActionForm form,
                            HttpServletRequest request,
                            HttpServletResponse response)
                            throws IOException, ServletException {
                            DynaActionForm searchForm = (DynaActionForm) form;
                            String isbn = (String) searchForm.get("isbn");
                            Book book = getBookService().read(isbn.trim());  |(2)
                            if (null == book) {
                            ActionErrors errors = new ActionErrors();
                            errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
                            saveErrors(request, errors);
                            return mapping.findForward("failure") ;
                            }
                            request.setAttribute("book", book);
                            return mapping.findForward("success");
                            }
                            }
                            

    在清單 4 中,您可以了解到如何創(chuàng)建 Struts 動作。在 (1) 處,我創(chuàng)建了一個 JavaBean 屬性。DelegatingRequestProcessor自動地配置這種屬性。這種設(shè)計(jì)使 Struts 動作并不知道它正被 Spring 管理,并且使您能夠利用 Sping 的動作管理框架的所有優(yōu)點(diǎn)。由于您的 Struts 動作注意不到 Spring 的存在,所以您不需要重寫您的 Struts 代碼就可以使用其他控制反轉(zhuǎn)容器來替換掉 Spring。

    DelegatingRequestProcessor 方法的確比第一種方法好,但是仍然存在一些問題。如果您使用一個不同的 RequestProcessor,則需要手動整合 Spring 的 DelegatingRequestProcessor。添加的代碼會造成維護(hù)的麻煩并且將來會降低您的應(yīng)用程序的靈活性。此外,還有過一些使用一系列命令來代替 Struts RequestProcessor 的傳聞。 這種改變將會對這種解決方法的使用壽命造成負(fù)面的影響。





    回頁首


    竅門 3. 將動作管理委托給 Spring

    一個更好的解決方法是將 Strut 動作管理委托給 Spring。您可以通過在 struts-config 動作映射中注冊一個代理來實(shí)現(xiàn)。代理負(fù)責(zé)在 Spring 環(huán)境中查找 Struts 動作。由于動作在 Spring 的控制之下,所以它可以填充動作的 JavaBean 屬性,并為應(yīng)用諸如 Spring 的 AOP 攔截器之類的特性帶來了可能。

    清單 5 中的 Action 類與清單 4 中的相同。但是 struts-config 有一些不同:


    清單 5. Spring 整合的委托方法
    <?xml version="1.0" encoding="ISO-8859-1" ?>
                            <!DOCTYPE struts-config PUBLIC
                            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
                            "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
                            <struts-config>
                            <form-beans>
                            <form-bean name="searchForm"
                            type="org.apache.struts.validator.DynaValidatorForm">
                            <form-property name="isbn"    type="java.lang.String"/>
                            </form-bean>
                            </form-beans>
                            <global-forwards type="org.apache.struts.action.ActionForward">
                            <forward   name="welcome"                path="/welcome.do"/>
                            <forward   name="searchEntry"            path="/searchEntry.do"/>
                            <forward   name="searchSubmit"           path="/searchSubmit.do"/>
                            </global-forwards>
                            <action-mappings>
                            <action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
                            <action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
                            <action    path="/searchSubmit"
                            type="org.springframework.web.struts.DelegatingActionProxy" |(1)
                            input="/searchEntry.do"
                            validate="true"
                            name="searchForm">
                            <forward name="success" path="/WEB-INF/pages/detail.jsp"/>
                            <forward name="failure" path="/WEB-INF/pages/search.jsp"/>
                            </action>
                            </action-mappings>
                            <message-resources parameter="ApplicationResources"/>
                            <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
                            <set-property
                            property="pathnames"
                            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
                            </plug-in>
                            <plug-in
                            className="org.springframework.web.struts.ContextLoaderPlugIn">
                            <set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
                            </plug-in>
                            </struts-config>
                            

    清單 5 是一個典型的 struts-config.xml 文件,只有一個小小的差別。它注冊 Spring 代理類的名稱,而不是聲明動作的類名,如(1)處所示。DelegatingActionProxy 類使用動作映射名稱查找 Spring 環(huán)境中的動作。這就是我們使用 ContextLoaderPlugIn 聲明的環(huán)境。

    將一個 Struts 動作注冊為一個 Spring bean 是非常直觀的,如清單 6 所示。我利用動作映射使用 <bean> 標(biāo)記的名稱屬性(在這個例子中是 "/searchSubmit")簡單地創(chuàng)建了一個 bean。這個動作的 JavaBean 屬性像任何 Spring bean 一樣被填充:


    清單 6. 在 Spring 環(huán)境中注冊一個 Struts 動作
    <?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="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
                            <bean name="/searchSubmit"
                            class="ca.nexcel.books.actions.SearchSubmit">
                            <property name="bookService">
                            <ref bean="bookService"/>
                            </property>
                            </bean>
                            </beans>
                            





    回頁首


    動作委托的優(yōu)點(diǎn)

    動作委托解決方法是這三種方法中最好的。Struts 動作不了解 Spring,不對代碼作任何改變就可用于非 Spring 應(yīng)用程序中。RequestProcessor 的改變不會影響它,并且它可以利用 Spring AOP 特性的優(yōu)點(diǎn)。

    動作委托的優(yōu)點(diǎn)不止如此。一旦讓 Spring 控制您的 Struts 動作,您就可以使用 Spring 給動作補(bǔ)充更強(qiáng)的活力。例如,沒有 Spring 的話,所有的 Struts 動作都必須是線程安全的。如果您設(shè)置 <bean> 標(biāo)記的 singleton 屬性為“false”,那么不管用何種方法,您的應(yīng)用程序都將在每一個請求上有一個新生成的動作對象。您可能不需要這種特性,但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如,當(dāng)實(shí)例化 Struts 動作時,<bean> 標(biāo)記的 init-method 屬性被用于運(yùn)行一個方法。類似地,在從容器中刪除 bean 之前,destroy-method 屬性執(zhí)行一個方法。這些方法是管理昂貴對象的好辦法,它們以一種與 Servlet 生命周期相同的方式進(jìn)行管理。





    回頁首


    攔截 Struts

    前面提到過,通過將 Struts 動作委托給 Spring 框架而整合 Struts 和 Spring 的一個主要的優(yōu)點(diǎn)是:您可以將 Spring 的 AOP 攔截器應(yīng)用于您的 Struts 動作。通過將 Spring 攔截器應(yīng)用于 Struts 動作,您可以用最小的代價處理橫切關(guān)注點(diǎn)。

    雖然 Spring 提供很多內(nèi)置攔截器,但是我將向您展示如何創(chuàng)建自己的攔截器并把它應(yīng)用于一個 Struts 動作。為了使用攔截器,您需要做三件事:

    1. 創(chuàng)建攔截器。
    2. 注冊攔截器。
    3. 聲明在何處攔截代碼。

    這看起來非常簡單的幾句話卻非常強(qiáng)大。例如,在清單 7 中,我為 Struts 動作創(chuàng)建了一個日志記錄攔截器。 這個攔截器在每個方法調(diào)用之前打印一句話:


    清單 7. 一個簡單的日志記錄攔截器
    package ca.nexcel.books.interceptors;
                            import org.springframework.aop.MethodBeforeAdvice;
                            import java.lang.reflect.Method;
                            public class LoggingInterceptor implements MethodBeforeAdvice {
                            public void before(Method method, Object[] objects, Object o) throws Throwable {
                            System.out.println("logging before!");
                            }
                            }
                            

    這個攔截器非常簡單。before() 方法在攔截點(diǎn)中每個方法之前運(yùn)行。在本例中,它打印出一句話,其實(shí)它可以做您想做的任何事。下一步就是在 Spring 配置文件中注冊這個攔截器,如清單 8 所示:


    清單 8. 在 Spring 配置文件中注冊攔截器
    <?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="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
                            <bean name="/searchSubmit"
                            class="ca.nexcel.books.actions.SearchSubmit">
                            <property name="bookService">
                            <ref bean="bookService"/>
                            </property>
                            </bean>
                            <!--  Interceptors -->
                            <bean name="logger"
                            class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1)
                            <!-- AutoProxies -->
                            <bean name="loggingAutoProxy"
                            class="org.springframework.aop.framework.autoproxy.
                            BeanNameAutoProxyCreator"> |(2)
                            <property name="beanNames">
                            <value>/searchSubmit</valuesgt; |(3)
                            </property>
                            <property name="interceptorNames">
                            <list>
                            <value>logger</value> |(4)
                            </list>
                            </property>
                            </bean>
                            </beans>
                            

    您可能已經(jīng)注意到了,清單 8 擴(kuò)展了 清單 6 中所示的應(yīng)用程序以包含一個攔截器。具體細(xì)節(jié)如下:

    • 在 (1) 處,我注冊了這個攔截器。
    • 在 (2) 處,我創(chuàng)建了一個 bean 名稱自動代理,它描述如何應(yīng)用攔截器。還有其他的方法定義攔截點(diǎn),但是這種方法常見而簡便。
    • 在 (3) 處,我將 Struts 動作注冊為將被攔截的 bean。如果您想要攔截其他的 Struts 動作,則只需要在 "beanNames" 下面創(chuàng)建附加的 <value> 標(biāo)記。
    • 在 (4) 處,當(dāng)攔截發(fā)生時,我執(zhí)行了在 (1) 處創(chuàng)建的攔截器 bean 的名稱。這里列出的所有攔截器都應(yīng)用于“beanNames”。

    就是這樣。就像這個例子所展示的,將您的 Struts 動作置于 Spring 框架的控制之下,為處理您的 Struts 應(yīng)用程序提供了一系列全新的選擇。在本例中,使用動作委托可以輕松地利用 Spring 攔截器提高 Struts 應(yīng)用程序中的日志記錄能力。





    回頁首


    結(jié)束語

    在本文中,您已經(jīng)學(xué)習(xí)了將 Struts 動作整合到 Spring 框架中的三種竅門。使用 Spring 的 ActionSupport 來整合 Struts(第一種竅門中就是這樣做的)簡單而快捷,但是會將 Struts 動作與 Spring 框架耦合在一起。如果您需要將應(yīng)用程序移植到一個不同的框架,則需要重寫代碼。第二種解決方法通過委托 RequestProcessor 巧妙地解開代碼的耦合,但是它的可擴(kuò)展性不強(qiáng),并且當(dāng) Struts 的 RequestProcessor 變成一系列命令時,這種方法就持續(xù)不了很長時間。第三種方法是這三種方法中最好的:將 Struts 動作委托給 Spring 框架可以使代碼解耦,從而使您可以在您的 Struts 應(yīng)用程序中利用 Spring 的特性(比如日志記錄攔截器)。

    三種 Struts-Spring 整合竅門中的每一種都被實(shí)現(xiàn)成一個完整可用的應(yīng)用程序。請參閱 下載 部分仔細(xì)研究它們。

    posted on 2008-12-22 13:49 一葉笑天 閱讀(166) 評論(0)  編輯  收藏 所屬分類: 開源技術(shù)
    主站蜘蛛池模板: 四虎国产精品免费视| 四虎永久精品免费观看| 人人鲁免费播放视频人人香蕉| 亚洲精品永久www忘忧草| 桃子视频在线观看高清免费完整| 国产日韩久久免费影院| 亚洲av日韩av无码| 亚洲人成人无码网www国产| 免费看韩国黄a片在线观看| 久久A级毛片免费观看| 亚洲日韩国产AV无码无码精品| 亚洲国产精品第一区二区 | 亚洲色图在线播放| 亚洲中久无码永久在线观看同| 一级特级女人18毛片免费视频| 无码专区—VA亚洲V天堂| 久久久久久A亚洲欧洲AV冫| 亚洲第一成人影院| 50岁老女人的毛片免费观看| 亚洲Av永久无码精品黑人| 亚洲精品午夜国产VA久久成人| 免费在线观看毛片| 免费国产一级特黄久久| 国产成人免费a在线视频色戒 | 亚洲国产成人AV网站| 亚洲日韩亚洲另类激情文学| 亚洲一级毛片免费在线观看| 亚洲最大的视频网站| 亚洲欧洲久久精品| 亚洲精品国产日韩| 久久被窝电影亚洲爽爽爽| 免费特级黄毛片在线成人观看 | 国产亚洲精品a在线无码| 国产亚洲成人久久| 国产精品久久久亚洲| 亚洲AV无码成人网站久久精品大| 亚洲人成色77777| 久久综合图区亚洲综合图区| 亚洲国产成人久久精品影视| 精品亚洲成a人片在线观看少妇 | 综合在线免费视频|