Spring 与 struts1 整合

smallbug

贡献于2013-02-19

字数:0 关键词: Spring JEE框架

1 吴 青 QQ:16910735 wuqing_bean@126.com 吴老师教学讲义 http://blog.sina.com/accpwulaoshi 忽然抚尺一下,群响毕绝。撤屏视之,一人、一桌、一椅、一扇、一抚 尺 而 已 吴老师教学讲义 2 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 Spring 与 struts1 整合 本节学习 Spring 如何与 Struts1 进行整合. 1. 为什么要将 Struts 与 Spring 整合? 通过前面的学习,我们知道 Struts 是一个 web 层的框架,使用 Action 来干活,在 Action 中又调用业务逻辑层来处理业务逻辑。我们可以认为 Action 类是一个控制器,它 控制着该调用哪个业务逻辑来完成任务,并根据业务逻辑方法的返回值确定因该使用哪个 视图来展现结果。 以往当我们在控制器(Action)中要调用业务逻辑组件的时候,主动创建了业务逻辑 组件,这样控制器就与具体的业务耦合在一起了,不利于维护和扩展。 每次请求到来的时候都创建业务逻辑组件,性能会下降,控制器只是业务逻辑组件的 使用者,而不应该负责创建实例。我们可以在 Action 中使用业务逻辑接口,然后利用 Spring 的 Ioc 容器,将创建的业务逻辑组件注入到 struts 的 action 中。这样 Action 就 不依赖于具体的业务逻辑了。 2. 如何进行整合 从上面的图中我们可以看到,使 用 Spring 的 IoC 将业务逻辑组件“注入”到 Action 中,那么 Action 必定要交由 Spring 来管理。我们说 Struts 与 Spring 的整合实际上就是 由 Spring 来接管 Action 的创建以及维护 Action 与业务组件之间的依赖关系。 这里我们需要思考两个问题: ActionServlet RequestProccessor Action 业务接口 业务组件 注入 Struts 框架 Spring IoC 容器 吴老师教学讲义 3 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 A) 在 javaSE 应用中使用 Spring 的时候,Spring 容器是我们通过实例化 BeanFactory 接口或者 ApplicationContext 接口(ApplicationContext 接 口是 BeanFactory 的子接口)的实现类来启动 Spring IoC 容器的,那么在 web 应用中 SpringIoC 容器什么时候启动,如何启动? B) 当请求到达Struts框架之后,当 Struts选择Action调用的时候,原来是Struts 框架自己实例化 Action 组件,而现在 Action 组件交给 Spring 管理了,那么 Struts 在如何获取由 Spring 管理的 Action 对象? 解决了这两个问题,我们就能顺利完成Spring与Struts的整合了。当Struts与Spring 整合之后,整个流程如下:当请求到达到 Struts 之后,Struts 到 SpringIoC 容器中获取 Action 实例,在 Spring 容器中为 Action“注入”业务逻辑组件,Struts 调用 Action 中 的 execute 方法,而 execute 方法中调用业务逻辑完成任务 3. 解决 Spring 容器启动问题 Spring 的 IoC 容器什么时候启动?因为我们是在 web 应用中使用 Spring,所以 Spring 容器必须在 web 请求到来之前启动,因 为 Struts 需要到 Spring 容器中获取Action。 关于启动 Spring 容器,我们有如下几种解决方案: A) 让 web 服务器启动的时候启动 Spring 容器 B) 让 MVC 框架启动 Spring 容器。 3.1 web 服务器启动 Spring 容器 在 web 应用中的 web.xml 添加一个监听器(Listener)或者添加一个 Servlet,这 个 Servlet 伴随服务器的启动而加载。Listener 是 Serlvet API 2.3 版本中加入的,现在的 服务器使用的基本都是 Servlet 2.3 以上的版本,所以都支持 Listener。在 Spring 中的 org.springframework.web.context 包中提供了以下几个接口和类:(查阅 SpringAPI 帮 助文档) 接口: WebApplicationContext 它从 ApplicationContext 接口继承而来,它的实例对象就是我们要创建的 web 应用 中的 Spring IoC 容器。 类:ContextLoaderListener 吴老师教学讲义 4 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 监听器类,它实现了 JavaEE 中的 ServletContextListener 监听器接口,是一种上下 文监听器,也就是监听 ServletContext。它以监听器的方式创建 Spring IoC 容器,也就 是 WebApplicationContext 接口的实现对象 类:ContextLoaderServlet 标准的 Servlet 类,继承了 HttpServlet。它以 Servlet 的方式创建 Spirng IoC 容器。 类:ContextLoader 它是 Spring 配置文件的装载器,负责装载 web 应用中配置的 Spring 配置文件。它 在 ContextLoaderListener 和 ContextLoaderServlet 中被调用。这个类中定义了一个 CONFIG_LOCATION_PARAM 常量,常量的值是: contextConfigLocation,表示配置文 件的位置。 API 中说道在需要在 web.xml 文件中配置一个 context-param 节点,这个节点表示上 下文参数,参数的名字为” contextConfigLocation”,其值为我们要加载的 Spring 的的配置文 件的路径,如果有多个,多个配置文件之间使用”,”进行分隔,也可以使用通配符“*”,如果 没有配置,则默认为“/WEB-INF/applicationContext.xml” 关于 Spring 配置文件的位置说明: 我们实际开发的时候,可以将配置文件放在 /WEB-INF/classes 目录中。如果使用 MyEclipse 工具,可以在 src 目录中建立 Spring 配置文件,编译之后,自动编译到了/WEB-INF/classes 目录中了。也可以将配置文件放 在/WEB-INF 的根目录中。 3.2 配置 contextConfigLocation 配置之前,先新建一个 web 项目,然后加入 Spirng 支持,将 Spring 的配置文件放 在 src 目录中,编译后自动放到了/WEB-INF/classes 目录中,在添加 Spring 支持的时候, 需要注意勾选 Spring web 库。上面提到的类在 spring-web.jar 中可以找到: 吴老师教学讲义 5 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 包含了 Spring 为 web 应用提供的类 将加入进来的 jar 包放到 /WEB-INF/lib 目录中 配置文件放在 src 目录中 吴老师教学讲义 6 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 加入完 Spirng 支持后,在 web.xml 文件中配置 context-param,即上下文参数,这 个参数中说明配置文件的路径: 3.3 使用监听器加载 Spring 容器 在 web.xml 文件中添加监听器 3.4 使用 Servlet 加载 Spring 容器 不管使用哪种方式启动 Spring 容器,最终 Spring 容器 WebApplicationContext 对象的实例被创建出来之后,被放到了 ServeltContext 中了(application 范围中)。 3.5 让 Struts 启动 Spring 容器 contextConfigLocation /WEB-INF/classes/applicationContext.xml <!-- 也可以写成 如果有多个使用","进行分隔 classpath:applicationContext.xml 加载以spirng开头的配置文件 classpath:spring*.xml --> org.springframework.web.context.ContextLoaderListener SpringContextServlet org.springframework.web.context.ContextLoaderServlet 1 吴老师教学讲义 7 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 除了用 web 服务器启动以外,也可以让 Struts 框架来启动。Struts 提供了 pulgin 可以进行扩展,在应用程序启动和关闭的时候,创建或者销毁某些资源。struts 插件类必 须实现 struts 中的 org.apache.struts.action. PlugIn 接口 Spring 中提供了 org.springframework.web.struts.ContextLoaderPlugIn 该类实 现了 struts 中的 PlugIn 接口,用于在 struts 框架启动的时候加载 Spring 容器 为项目中添加 Struts 支持,在 Struts 的配置文件 Struts-config.xml 文件中添加如下 配置: 这样,在 Struts 启动的时候,也会将 Spring 容器加载,同样也是放到了 ServletContex 中了。其 key 是【org.springframework.web.struts.ContextLoaderPlugIn.CONTEXT】,这个 可以通过在 Log4j 的日志文件可以看到.注意这个 key 与使用 web 容器启动方式启动时的 key 不一样。 3.6 使用哪种方式 上面讲解了两种 web 启动的方式,一种是 web 服务器启动,该方式即可以使用监听 器,也可以使用 servlet 来启动。第二种方式是使用 Struts 框架插件来启动。不管使用哪 种方式,都可以将 Spring 容器启动起来,所以我们只需要选择其中一种即可。 4. Struts 框架如何找到 spirng 中托管的 Action 对象 我们编写的 Action 类和业务逻辑类都在 Spring 容器中进行配置。当 Struts 收到请 求之后,需要调用 Action“干活”,而 Action 现在已经被 Spring 实例化出来了,不再 需要 Struts 自己去实例化,那么 Struts 如何从 Spring 容器中获取 Action 对象呢? 首先看看 struts 如何处理请求的:请求被 ActionServlet 拦截,ActionServlet 中把 请求交给了 RequestProcessor, RequestProcessor 通过取得 用户提交的 action 路径 再从 struts-config.xml 中获取该路径所对应的 Action,将请求交给这个 Action. 现在这个 Action 已经被 Spring 管理起来了,那么 ActionServelt 如何找 Spring 要 到这个 Action 对象的实例? 吴老师教学讲义 8 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 Spring 为我们准备了两种代理类,一种是 Action 的代理类 DelegatingActionProxy 一种是请求处理器代理类 DelegatingRequestProcessor。可以通过这两个类中其中一个 来获取 Spring 容器中的 Action 对象。 4.1 使用 DelegatingActionProxy org.springframework.web.struts.DelegatingActionProxy,这个类是 Struts 中 Action 类的子类.struts 就通过这个由 Spring 提供的代理类来与 Spring 容器沟通 。 在我们单独使用 Struts 的时候,编写了 Action 类之后,需要在 Struts-config.xml 文件中对这个 Action 进行配置,现在我们需要在 struts-config.xml 文件中将所有的 action 都定义成 DelegatingActionProxy。这样 requestProcessor 调用的永远都是这 个 DelegatingActionProxy,再由 DelegatingActionProxy 到 Spring 容器中找到真正 要调用的 Action 对象,然后对他进行调用,其过程如下图: 编写一个业务接口 HelloService: 业务接口的实现类 ActionServlet RequestProcessor DelegatingActionProxy Spring容器中的 Action RequestProcessor 调用的永远都是 DelegatingActionProxy , 因 为所有真正“干活”的 Action 都在 Spring 容器中,必须要通 过这个代理类来获取 Spring 容 器 中 的 action 对象。 所以 struts-config.xml文件中所有 的 Action 都必须配置成代理, 如果还在 struts-config.xml 文件中 配置我们编写的 Aciton,则 Struts 会直接实例 化它。 public interface HelloService { public String sayHello(String name); } public class HelloServiceImpl implements HelloService { public String sayHello(String name) { return "你好,"+name; } 吴老师教学讲义 9 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 这里我们编写一个简单的 Action:HelloAction,这个 Action 使用业务接口,让 spirng 将 业务实现类如入进来: 在 struts-config.xml 文件中配置 Action,注意这里配置的 type 不能是 HelloAction, 而因该是 DelegatingActionProxy 。如果配置 HelloAction,struts 就会直接实例化 HelloAction 了,那么 helloService 就是 null,执行的时候就会出现空指针异常。 在 Spring 配置文件 applicationContext.xml 文件中配置 action 和业务类,并为 action 注入业务对象。 public class HelloAction extends Action { private HelloService helloService; //通过Spring注入 public void setHelloService(HelloService helloService) { this.helloService = helloService; } @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println(helloService.sayHello("张三")); return null; } } 吴老师教学讲义 10 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 启动 web 应用,action 正确执行。 4.2 DelegatingRequestProcessor 这个类扩展了 struts 中的 RequestProcessor,即 DelegatingRequestProcessor 是 RequestProcessor 类的子类。当请求到达 RequestProcessor 的时候,就会进入到 DelegatingRequestProcessor 中,此时代理处理器(DelegatingRequestProcessor)就 会根据 struts-config.xml 文件中的 path 的配置到 Spring 容器中获取 Action,然后执行 action 了。 上图与前面我们使用 DelegatingActionProxy 看起来好像是差不多的。其实有很大 的差别。 使用 DelegatingActionProxy 的处理过程:当请求经过 struts 的 RequestProcessor 的时候,RequestProcessor 需要去实例化在 struts-config.xml 文件中配置的代理,即 DelegatingActionProxy,完事之后。DelegatingActionProxy 再到 Spring 容器中获取 Action 对象。 而 使用 DelegatingRequestProcessor 的 处理过程: 当 请求经过 struts 的 RequestProcessor 的时候, RequestProcessor 不需要实例化任何 action,而是将控制 权 交给了 DelegatingRequestProcessor , DelegatingRequestProcessor 直接到 Spring 容器中获取 Action 对象。 所以它们两个的 区别就 在于使用 DelegatingActionProxy 是 需要在 struts-config.xml 文件中配置 action 的 type 属性的,这个属性的值只能是: org.springframework.web.struts.DelegatingActionProxy。而使用 ActionServlet RequestProcessor DelegatingRequestProcessorSpring容器中的Action 吴老师教学讲义 11 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 DelegatingRequestProcessor 的时候,不需要在 struts-config.xml 文件的 action 中配置 type 属性,即使配置了也不会有任何作用。但是使用 DelegatingRequestProcessor 需要 在 struts-config.xml 文件中配置控制器: 下面是使用 DelegatingRequestProcessor 的时候,struts-config.xml 文件的配置: 5. 总结 启动 Spring 容器,我们可以使用 监听器的方式(在 web.xml 中配置监听器,监听器类由 Spring 提供) Servlet 的方式(在 web.xml 中配置 servlet,servlet 类由 Spring 提供) Struts 插件的方式(在 struts-config.xml 中配置,插件由 spring 提供) 到 spring 容器中获取 action 对象,我们可以使用: Action 代理(DelegatingActionProxy):struts 框架实例化 DelegatingActionProxy 对象,DelegatingActionProxy 再到 spring 容器中取出 action 处理器代理(DelegatingRequestProcessor):struts 通过 DelegatingRequestProcessor 直接到 spirng 容器中取出 action 不需要配置 type 属性,即使配置了 也不会起作用

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档

相关文档