三种整合技术(或者窍门)都有自己的优点和特点。我偏爱其中的一种,但是我知道这三种都能够加深您对 Struts 和 Spring 的理解。在处理各种不同情况的时候,这将给您提供一个广阔的选择范围。无论使用哪种技术,都需要使用 Spring 的 ContextLoaderPlugin
为 Struts 的 ActionServlet
装载 Spring 应用程序环境。方法如下:
- 使用 Spring 的
ActionSupport
类整合 Structs - 使用 Spring 的
DelegatingRequestProcessor
覆盖 Struts 的RequestProcessor
- 将 Struts
Action
管理委托给 Spring 框架
org.springframework.web.struts.ActionSupport
类提供了一个 getWebApplicationContext()
方法。您所做的只是从 Spring 的 ActionSupport
而不是 Struts Action
类扩展Action。org.springframework.web.struts.DelegatingRequestProcessor
类来覆盖 Struts 的 RequestProcessor
处理程序。DelegatingRequestProcessor
方法的确比第一种方法好,但是仍然存在一些问题。如果您使用一个不同的RequestProcessor
,则需要手动整合 Spring 的 DelegatingRequestProcessor
。添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。此外,还有过一些使用一系列命令来代替 Struts RequestProcessor
的传闻。 这种改变将会对这种解决方法的使用寿命造成负面的影响。struts-config
Action映射中注册一个代理来实现。代理负责在 Spring 环境中查找 StrutsAction。由于Action在 Spring 的控制之下,所以它可以填充Action的 JavaBean 属性,并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。
Action委托解决方法是这三种方法中最好的。StrutsAction不了解 Spring,不对代码作任何改变就可用于非 Spring 应用程序中。RequestProcessor
的改变不会影响它,并且它可以利用 Spring AOP 特性的优点。
Action委托的优点不止如此。一旦让 Spring 控制您的 StrutsAction,您就可以使用 Spring 给Action补充更强的活力。例如,没有 Spring 的话,所有的 StrutsAction都必须是线程安全的。如果您设置 <bean>
标记的 singleton 属性为“false”,那么不管用何种方法,您的应用程序都将在每一个请求上有一个新生成的Action对象。您可能不需要这种特性,但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如,当实例化 StrutsAction时,<bean>
标记的 init-method 属性被用于运行一个方法。类似地,在从容器中删除 bean 之前,destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法,它们以一种与 Servlet 生命周期相同的方式进行管理。
Action委托也有两种做法:
(1) 把Action配置在beans.xml里,利用Spring初始化Action的bean
注意:此时strut.xml中配置的action的class值,应该与spring中配置的Action Bean id相应。
(2) 不需要在beans.xml里配置Action,利用Struts-Spring_Plugin插件自动初始化Action
如果action不是使用Spring ObjectFactory创建的话,插件提供了两个拦截器来自动装配action,默认情况下框架使用的自动装配策略是name,也就是说框架会去Spring中寻找与action属性名字相同的bean,可选的装配策略还有:type、auto、constructor,我们可以通过常量struts.objectFactory.spring.autoWire来进行设置。
Spring插件具体有如下几个作用:
— 允许Spring创建Action、Interceptror和Result。
— 由Struts创建的对象能够被Spring装配。
— 如果没有使用Spring ObjectFactory,提供了2个拦截器来自动装配action。