论坛首页 Java企业应用论坛

Spring与Struts2整合

浏览 4786 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2014-01-02  
Spring与Struts2
15.2.1概述
以上面的示例来说明整合Spring和Struts2的基本方式:
SampleAction与SampleService的生命周期和依赖关系都由Spring去管理。
Struts2需要SampleAction实例的时候,不是自己新建实例,而是向Spring去请求获取一个实例,也就是SampleAction实例的生命周期也由Spring来管理
接下来就来具体看看怎么整合Spring与Struts2。
15.2.2拷入jar包
要整合Spring和Struts2,需要先要拷入Spring需要的jar包,既包括Spring本身的jar包,也包括Struts2的Spring插件。
       找到下载的Struts2的资源包中的lib文件夹,也就是struts-2.1.8.1\lib,将以下几个jar包拷入到我们的web工程的WEB-INF\lib中:spring-beans-2.5.6.jar、spring-context-2.5.6.jar、spring-core-2.5.6.jar、spring-test-2.5.6.jar、spring-web-2.5.6.jar、struts2-spring-plugin-2.1.8.1.jar、commons-logging-1.0.4.jar、struts2-spring-plugin-2.1.8.1.jar。
15.2.3改写SampleAction
       由于现在和Spring结合了,可以由Spring为Action注入Action需要的SampleService的实例,也就是SampleAction引用SampleService的方式需要改变,其他的没有变化,示例代码如下:

java代码:
查看复制到剪贴板打印
public class SampleAction extends ActionSupport{ 
    //通过setter方式,由Spring来注入SampleService实例 
    private SampleService service;   
    public void setService(SampleService service) { 
        this.service = service; 
    } 
    private String name; 
    private String userId; 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
    public String getUserId() { 
        return userId; 
    } 
    public void setUserId(String userId) { 
        this.userId = userId; 
    } 
     
    public String execute() throws Exception { 
        name = this.service.getNameById(userId);         
        return SUCCESS; 
    } 

在execute方法中不再直接新建SampleServiceImpl的实例了,而是声明了一个SampleSerivce类型的属性,并提供对应的setter方法,这个setter方法是留给Spring注入对象实例的时候调用的,可以不用提供getter方法。
       也就是说,现在的SampleAction已经不用知道逻辑层的具体实现了。
15.2.4编写Spring的配置文件applicationContext.xml
       要让Spring来管理SampleAction和SampleServiceImpl的实例,还需要新建一个Spring的配置文件。在src下新建一个applicationContext.xml文件,内容如下:

java代码:
查看复制到剪贴板打印
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation=" 
            http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 
    <bean name="sampleService" class="cn.javass.spring.SampleServiceImpl"/> 
     
    <bean name="sampleAction" class="cn.javass.spring.SampleAction" scope="prototype"> 
        <property name="service" ref="sampleService"/> 
    </bean> 
</beans> 
这个xml的根元素是<beans>,在<beans>中声明了它的schema引用,除此之外,还有两个<bean>元素,定义了由Spring管理的SampleServiceImpl和SampleAction。
对于第一个<bean>元素来说
l         name属性为它设置了一个名字
l         class元素指定了它的实现类的全类名
对于第二个<bean>元素来说
l         name属性和class属性的含义与第一个<bean>元素完全一样。
l         scope属性,赋值为prototype(原型)。scope属性非常重要,它管理了注册在它里面的Bean的作用域。Spring容器默认的作用域是单例,即每次外界向Spring容器请求这个Bean,都是返回同一个实例;但是,Struts2的Action是需要在每次请求的时候,都要新建一个Action实例,所以,在配置对应Action的<bean>元素时,必须把它的scope属性赋值为prototype,以保证每次请求都会新建一个Action实例。
l         <property>子元素。<property>元素的name属性为service,代表SampleAction这个类有一个setter方法叫setSampleService;<property>元素的ref属性为sampleService,代表Spring容器会将一个名为sampleService的已经存在的Bean,注入给sampleAction的service属性。
15.2.5在web.xml中引用Spring配置文件
       有了applicationContext之后,还要在Web环境下引用它,web.xml的示例为:

java代码:
查看复制到剪贴板打印
<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
     <context-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>classpath*:applicationContext.xml</param-value> 
    </context-param> 
       
    <listener> 
        <listener-class> 
            org.springframework.web.context.ContextLoaderListener 
        </listener-class> 
    </listener> 
     
    <filter> 
        <filter-name>Struts2</filter-name> 
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>Struts2</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
</web-app> 
listener实现了当这个Web工程启动的时候,就去读取Spring的配置文件,这个类是由Spring提供的,这里只需要配置上去就可以了。
上下文参数的配置里面,contextConfigLocation的值classpath*:applicationContext.xml,表明了所有出现在classpath路径下的applicationContext.xml文件,都是上面的这个Listener要读取的Spring配置文件。
15.2.6修改struts.xml
就快要大功告成了,最后一步,来修改struts.xml,需要做两件事:
       首先,添加常量struts.objectFactory,其值为spring,这就指定了Struts2使用Action的时候并不是自己去新建,而是去向Spring请求获取Action的实例。示例如下:

java代码:
查看复制到剪贴板打印
<constant name="struts.objectFactory" value="spring"/> 
然后,<action>元素的class属性,现在并不是要填Action类的全类名了,而是要填一个在Spring配置文件中配置的Action的Bean的名字,也就是<bean>元素的name属性,很显然,需要的是sampleAction这个Bean。示例如下:

java代码:
查看复制到剪贴板打印
<package name="helloworld" extends="struts-default"> 
     <action name="sampleAction" class="sampleAction"> 
<result>/spring/success.jsp</result> 
lt;/action> 
</package> 
只有<action>元素的class属性变了,其他部分不变。
       来测试一下,运行:http://localhost:9080/helloworld/sampleAction.action?userId=test。
运行一切正常,对吧,这也说明Struts2与Spring整合并不是为了实现新功能,而是为了让表现层组件和逻辑层组件解耦,SampleAction类不用再知道SampleServiceImpl这个具体实现了,只需要知道SampleService这个接口就可以了。
私塾在线网站原创《研磨struts2》系列
   发表时间:2014-01-02  
Spring容器默认的作用域是单例,即每次外界向Spring容器请求这个Bean,都是返回同一个实例;但是,Struts2的Action是需要在每次请求的时候,都要新建一个Action实例,所以,在配置对应Action的<bean>元素时,必须把它的scope属性赋值为prototype,以保证每次请求都会新建一个Action实例。
是什么意思啊?  不太明白~~~~ 能请教下么 谢谢~~
0 请登录后投票
   发表时间:2014-01-03  
sniperdj 写道
Spring容器默认的作用域是单例,即每次外界向Spring容器请求这个Bean,都是返回同一个实例;但是,Struts2的Action是需要在每次请求的时候,都要新建一个Action实例,所以,在配置对应Action的<bean>元素时,必须把它的scope属性赋值为prototype,以保证每次请求都会新建一个Action实例。
是什么意思啊?  不太明白~~~~ 能请教下么 谢谢~~


Struts的action如果交予spring来托管时,默认action实例的生成策略是singleton的,现在好多人喜欢在action定义状态变量,这样的情况下单例action会出现并发问题,所以文章中的意思是要设置为prototype。

其实吧,完全不用将action托管给Spring,让Struts自己管理,Struts2本身就会在每次请求new一个新的action实例了。
0 请登录后投票
   发表时间:2014-01-04  
都合体N年了。
0 请登录后投票
   发表时间:2014-01-06  
sniperdj 写道
Spring容器默认的作用域是单例,即每次外界向Spring容器请求这个Bean,都是返回同一个实例;但是,Struts2的Action是需要在每次请求的时候,都要新建一个Action实例,所以,在配置对应Action的<bean>元素时,必须把它的scope属性赋值为prototype,以保证每次请求都会新建一个Action实例。
是什么意思啊?  不太明白~~~~ 能请教下么 谢谢~~



其实这个意思是指,单例模式是指action只在初始化的时候只创建一次,相当于全局变量,所以你每次请求这个action总是这一个bean,如果是prototype这个模式,那么就会在你每次请求同一个action的时候都会创建一个新的的action对象。
0 请登录后投票
   发表时间:2014-03-30  
框架 就是好哈
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics