我们再来看一段Action源代码:
public class CourceAction extends ActionSupport {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
//取得Spring上下文
ApplicationContext context = super.getWebApplicationContext();
//取得CourceService Bean
CourseService courseService = (CourseService) context.getBean("courseService");
Set allCources = courceService.getAllCources(); request.setAttribute("cources", allCources);
//..........the other statements.
return mapping.findForward("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)的原则.
4.实现第二种集成方案:代理和委托Action.
这种集成方案要求我们编写一个Struts Action,但它只不过是一个包含在Spring应用上下文中的真正Struts Action的一个代理.该代理Action从Struts插件ContextLoaderPlugIn中获取应用上下文,从中查找真正的Struts Action,然后将处理委托给真正的Struts Action.这个方法的幽雅之处在于:只有代理action才会包含Spring特定的处理.真正的Action可以作为org.apache.struts.Action的子类来编写.
下面我们来看一段在之中集成方式下的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 = courceService.getAllCources();
request.setAttribute("cources", allCources);
//..........the other statements.
return mapping.findForward("jspView");
}
/* 注入CourceService */
public void setCourceService(CourceService courceService) {
this.courceService = courceService;
}}
分析:大家可以看到,在这种方式之下,我们的Struts Action类和Spring是低耦合的,它仅仅依赖了Spring提供的反向控制(IoC)机制把CourceService注入到了我们的Action中.到此,大家肯定会有一个疑问:那就是Spring到底是如何提供IoC反向控制的呢?