JakartaStruts是Apache軟件組織提供的一個開源項目它為Java Web應用提供了基於ModelViewController的MVC框架尤其適用於開發大型可擴展的Web應用盡管基於Java的MVC框架層出不窮事實上Spring的MVC模型也提供了驅動應用系統Web層的能力但JakartaStruts仍然是所有這些框架中的佼佼者
Spring是一個輕量級(大小和系統開支的角度)的IoC和AOP容器它力圖簡化JEE開發即JEE without EJB而且作為幫助企業級開發的核心支柱Spring為模型層(OR持久層:HibernateJDOiBatis等)服務層(EJBJNDIWebService)以及表現層(StrutsJSFVelocity)都提供了良好的支持和集成方案
首先我們來看一個SpringStruts整合應用下的控制器Action類源代碼
public class CourceAction extends Action
{
private CourceService courceService;
public ActionForward execute( ActionMapping mapping ActionForm form HttpServletRequest request HttpServletResponse response) throws Exception
{ Set allCources = courceServicegetAllCources(); //the other statements requestsetAttribute("cources" allCources);
return mappingfindForward("jspView");
}
}
分析:CourceService為一個業務實現的接口此接口聲明了一系列的業務處理方法該方法的實現配置為Spring上下問的一個Bean由此看來我們大家都可能會產生一個疑問:Struts action如何取得一個包含在Spring上下文中的Bean呢?為了回答這個問題Spring提供了兩種與Struts集成的方式:
()從一個知曉Spring上下文的基類派生我們自己的Struts Action類然後在派生類中就可以使用superXX()方法來獲得一個對Spring受控Bean的引用
()將請求委托給作為Spring Bean管理的Struts Action來處理
注冊Spring插件:為了使Struts Action能夠訪問由Spring管理的Bean我們就必須要注冊一個知道Spring應用上下文的Struts插件可以在strutsconfigxml中通過如下的方式來完成注冊
< plugin classname="orgspringframeworkwebstrutsContextLoadPlugin">
< setproperty value="WEBINF/Yhcipxml" property="contextConfigLocation"> < /PLUGIN>
ContextLoadPlugin()負責裝載一個Spring應用上下文(具體的說:是一個WebApplicationContext)value屬性值為要加載的配置Spring受控Bean的xml文件的URI
完成第一種集成方案:實現一個知曉Spring的Action基類
這種集成方案是從一個公共的能夠訪問Spring應用上下文的基類中派生所有的Struts Action但值得慶幸的是:我們不用自己去編寫這個知曉Spring應用上下文的基類因為Spring已經提供了orgspringframeworkwebstrutsActionSupport:一個orgapachestrutsactionAction的抽象實現它重載了setServlet()方法以從ContextLoaderPlugin中獲取WebapplicationContext因此任何時候我們只需要調用supergetBean()方法即可獲得一Spring上下文中的一個Bean的引用
我們再來看一段Action源代碼:
public class CourceAction extends ActionSupport
{
public ActionForward execute(
ActionMapping mapping ActionForm form HttpServletRequest request HttpServletResponse response) throws Exception
{ //取得Spring上下文 ApplicationContext context = supergetWebApplicationContext();
//取得CourceService Bean CourseService courseService = (CourseService) contextgetBean("courseService");
Set allCources = courceServicegetAllCources();
requestsetAttribute("cources" allCources);
//the other statements return mappingfindForward("jspView"); }}
分析:這個Action類由ActionSupport派生當CourceAction需要一個Spring受控Bean時:它首先調用基類的getWebApplicationContext()方法以取得一個Spring應用上下文的引用;接著它調用getBean()方法來獲取由Spring管理的courceService Bean的一個引用
小結
至此我們已經用第一種方案圓滿的完成了Spring與Struts的集成工作這種集成方式的好處在於直觀簡潔容易上手除了需要從ActionSupport中派生以及需要從應用上下文中獲取Bean之外其他都與在非Spring的Struts中編寫和配置Action的方法相似但這種集成方案也有不利的一面最為顯著的是:我們的Action類將直接使用Spring提供的特定類這樣會使我們的Struts Action(即控制層)的代碼與Spring緊密耦合在一起這是我們不情願看到的另外Action類也負責查找由Spring管理的Bean這違背了反向控制(IoC)的原則
實現第二種集成方案:代理和委托Action
這種集成方案要求我們編寫一個Struts Action但它只不過是一個包含在Spring應用上下文中的真正Struts Action的一個代理該代理Action從Struts插件ContextLoaderPlugIn中獲取應用上下文從中查找真正的Struts Action然後將處理委托給真正的Struts Action這個方法的幽雅之處在於:只有代理action才會包含Spring特定的處理真正的Action可以作為orgapachestrutsAction的子類來編寫
下面我們來看一段在之中集成方式下的Struts Action源代碼:
public class CourceAction extends Action
{ private CourceService courceService; public ActionForward execute( ActionMapping mapping ActionForm form HttpServletRequest request HttpServletResponse response) throws Exception
{ Set allCources = courceServicegetAllCources();
requestsetAttribute("cources" allCources); //the other statements return mappingfindForward("jspView");
} /* 注入CourceService */
public void setCourceService(CourceService courceService)
{ thiscourceService = courceService;
}
}
分析:大家可以看到在這種方式之下我們的Struts Action類和Spring是低耦合的它僅僅依賴了Spring提供的反向控制(IoC)機制把CourceService注入到了我們的Action中到此大家肯定會有一個疑問:那就是Spring到底是如何提供IoC反向控制的呢?回答這個問題我們需要完成兩個步驟的配置:
()在strutsconfigxml中注冊Struts Action但要注意的是我們在這裡注冊的是代理Action幸運的是我們不必親自編寫這個類因為Spring已經通過orgspringframeworkwebstrutsDelegatingActionProxy提供了這個代理的Action具體的配置方法如下:
< action type="orgspringframeworkwebstrutsDelegatingActionProxy" path="/listCourses">
()將真正的Struts Action作為一個Spring Bean並在Spring上下文配置文件中作為一個Bean注冊之並將Action所要引用的courceService注入給它
< bean class="comeRedCIPwebCourceAction" name="/listCourses"> < property name=""> < ref bean="courseService"> < /property> < /bean>
注意:name屬性的值是非常重要的它必須和strutsconfigxml中的path屬性完全一致這是因為DelegatingActionProxy會使用path屬性值在Spring上下文中查找真正的Action使用DelegatingActionProxy的好處在於我們可以不使用任何Spring特定的類來編寫Struts Action同時Struts動作能夠利用IoC取得和他合作的對象唯一不足之處就是不太直觀配置相對復雜為了使action委托顯得更為直觀一些我們可對這種集成方案做進一步的改進:使用請求委托
使用請求委托
為了使action委托看上去更為直觀一些Spring提供了DelegatingRequestProcessor另一種專門用於Spring的請求處理器需要在strutsconfigxml中做如下配置:
< controller processorclass="orgspringframeworkwebstrutsDelegatingRequestProcessor">
這樣DelegatingRequestProcessor將告訴Struts自動將動作請求委托給Spring上下文中的Action來處理這使得我們可以在strutsconfigxml中用struts action的真正類型來聲明它們例如:
< action type="comeRedCIPwebCourceAction" path="/listCourses">
當接受到一個針對/listCourses的請求時DelegatingRequestProcessor會自動從Spring上下文配置文件中查找一個名為/listCourses的Bean(實為一個Struts Action)類
< action type="comeRedCIPwebCourceAction" path="/listCourses">
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/20546.html