zoukankan      html  css  js  c++  java
  • Spring整合Struts的两种方式介绍

    1 使用Spring托管Struts Action

    该种方式就是将Struts Action也视为一种Bean交给Spring来进行托管,使用时Struts的配置文件中配置的Action的classs属性不再是具体Action的实现类,而是在Spring配置文件中配置的BeanID,也就是说具体是Action实现类是在Spring的配置文件中进行配置的,Struts的配置文件中的Class属性只是Spring文件中Bean的ID。Struts配置文件如下示例:

    <action name="LoginAction" class="loginAction">
    
           <!--登录Action com.simpleworkflow.action.LoginAction-->
    
           <result name="input">/WEB-INF/content/login.jsp</result>
    
            <result name="mgr">/WEB-INF/content/manager/index.jsp</result>
    
            <result name="emp">/WEB-INF/content/employee/index.jsp</result>
    
            <result name="error">/WEB-INF/content/login.jsp</result>
    
    </action>

    同时需要在Struts配置文件中加入如下配置:

    <struts>
    
        <constant name="struts.objectFactory" value="spring" />
    
    </struts>

    而Spring的配置文件中有如下配置:

    <!--配置Action-->
    
    <bean id="loginAction" class="com.simpleworkflow.action.LoginAction" scope="prototype">
    
        <!--登录验证Action-->
    
        <property name="empService" ref="employeeOperator"/>
    
        <property name="mgrService" ref="managerOperator"/>
    
    </bean>

    可以看到,在Spring中配置的Bean的Class属性才是该Action的具体实现类,而且还可以为该Action设置其行为,该行为可以有singleton、prototype、request、session、global Session几个值(几个值的详细解释请参考Spring Bean介绍),由于Web环境下,Action通常是无状态的,即每个HttpRequest对应一个Action,请求完成后该Action就应该进行释放,而不是继续保留供其他请求使用,因此,Action的Scope属性的值通常设为prototype,表示每次请求都会产生一个新的实例。

    需要注意的是,为了完成Spring托管Struts Action,必须加入一个包,该包为:struts2-spring-plugin-2.2.1.jar,或者其他版本。如果系统中加入了该包,那么就不需要在Struts配置文件中加入<constant/>配置了,该常量配置是指示Action的创建者由Struts变为Spring。为什么加入了该包以后就不需要加入<constant/>的配置了呢?这是由于在包内定义了一个struts-plugin.xml的文件,该文件内容如下所示:

    <struts>
    
         <!—创建Action的类变为了StrutsSpringObjectFactory-->
    
        <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
    
        <!--  Make the Spring object factory the automatic default -->
    
        <constant name="struts.objectFactory" value="spring" />
    
        <constant name="struts.class.reloading.watchList" value="" />
    
        <constant name="struts.class.reloading.acceptClasses" value="" />
    
        <constant name="struts.class.reloading.reloadConfig" value="false" />
    
        <package name="spring-default">
    
            <interceptors>
    
                <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
    
                <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
    
            </interceptors>
    
        </package>   
    
    </struts>

    由于这种方式Struts配置文件中指定的Action的Class属性并不是真实的实现类,因此破坏了Struts配置文件的原生性,并且需要在Spring中添加Action的配置文件,造成大量的配置冗余,因此更加推荐自动装配的方式。

    2 自动装配方式(推荐)

    由Spring托管Struts Action的方式(方式1)将Action的创建者由Struts改变为Spring,Action不再由Struts核心进行创建,而是类似应用中的其他Bean一样由Spring进行容器在初始化时进行创建。自动装配则不然,它会用Struts2配置文件中的class属性去和Spring配置文件中的id属性进行关联(存在一个寻找过程),如果能找到则由Spring创建,否则由Struts2框架自身创建,然后由Spring来装配。所以Action的实际创建者仍然是Struts(没人会拿包路径当BeanID),Spring只是负责装配。

    同样需要引入上面介绍的包(必须引入该包了),并且在Struts.xml中加入如下常量属性配置(必须):

    <constant name="struts.objectFactory.spring.autoWire" value="true"></constant>

    但是Struts配置文件中Action的Class属性不再是BeanID,而是实际的Action类。

    <action name="loginAction" class="com.huateng.framework.action.LoginAction">
    
           <result name="emperorsuccess">/fpages/emperorMain.jsp</result>
    
           <result name="adminsuccess">/fpages/admin.jsp</result>
    
           <result name="queensuccess">/fpages/queenMain.jsp</result>
    
           <result name="ministersuccess">/fpages/ministerMain.jsp</result>
    
           <result name="input">/fpages/login.jsp</result>
    
    </action>

    而在Spring配置文件中不需要再次配置该Action。

    3   方式1、2的对比

    方式一中加入额外插件,可加可不加常量配置语句,Action的创建者为Spring,他会根据Action的Class属性的值搜索Spring配置文件,找到Bean Id为Class属性值的Bean。Action由Spring在初始化时创建并完成后续的装载(装载:在Action中使用的其他Bean由Spring容器生成,并注入到Action中去。详见4.4)。由于需要在两个配置文件中添加配置,因此容易造成配置冗余。

    方式二加入了额外插件,以及在Struts配置文件中加入一条常量配置,Action的实际创建者仍为Struts,Spring只是负责为创建好的Action注入所需要的逻辑组件。

    方式1

    方式2

    使用方法

    加入插件;

    加插件,加常量配置

    Action的创建者

    Spring

    在容器中寻找,找到则为Spring,未找到则为Struts

    插件中的组件装配拦截器是否起作用

    插件中的拦截器起作用。Spring负责注入逻辑组件。

    插件中的拦截器起作用。Spring负责注入逻辑组件。

    4 使用Spring管理Struts中使用到的Bean

    使用自动装配方式来整合Spring和Struts,Struts的配置文件—struts.xml中Action的定义方式不需要做任何改变,但是需要在web.xml中配置Spring的配置文件,来加载Bean的定义文件,加载后容器就会托管已经定义好的Bean,而在Action中,只需要定义需要注入的Bean,比如Service等,同时设置好Setter方法和Getter方法,在execute方法中直接使用该Bean的方法即可。

    需要改变的地方有:

    需要打开Spring托管Struts的开关,该开关相当于是告知Spring,要负责为定义的Action注入所需的逻辑组件。在Struts.xml中添加如下语句(方式2需要加入,如果是方式一不需要):

    <constant name="struts.objectFactory.spring.autoWire" value="true"></constant>

    变量struts.objectFactory.spring.autoWire的值设置为true即为标识自动装配打开,Spring容器会自动根据在Struts Action类中定义的Bean的名字查找容器中是否有该容器的定义,如果有,就自动为该类(Action)注入该Bean,如果没有那么就无法完成注入。

    这种策略下,Struts的配置文件和不整合Spring时没有区别(需要加入上面的语句)。区别在于如果是方式1,Action的创建者是Spring,那么后续的装配自然由Spring容器完成。而方式2由于Action的实际创建者仍然是Struts,而Spring容器只是负责为创建好的Action实例注入所需要的逻辑组件而已。

    5     struts.objectFactory和struts.objectFactory.spring.autoWire

    struts.objectFactory这个属性用于说明Struts2的对象池创建工厂,Struts2也有自己的对象池,就像Spring那样,在配置文件中你可以引用对象池中的对象,你可以借助于Spring中的对象池,当想要得到Spring中的对象池时,申明struts.objectFactory为Spring的对象池构建工厂。当指定struts.objectFactory为spring时,struts2框架就会把bean转发给spring来创建,装配,注入。但是bean创建完成之后,还是由struts容器来管理其生命周期。

    在struts.xml中的代码如下:

    <constant name="struts.objectFactory" value="spring" />

    struts.objectFactory.spring.autoWire是用spring插件通过覆盖(override)Struts2的 ObjectFactory来增强核心框架对象的创建。当创建一个对象的时候,它会用Struts2配置文件中的class属性去和Spring配置文件中的id属性进行关联,如果能找到则由Spring创建,否则由Struts2框架自身创建,然后由Spring来装配。

    Spring插件(struts2-spring-plugin-2.2.1.jar)具体有如下几个作用:

    1. 允许spring来创建Action、Interceptror和Result;

    2. 由Struts创建的对象能够被Spring装配;

    3. 提供了2个拦截器来自动装配action;

    这里要注意的是,我们不必在Spring中去注册action,尽管我们可以这么去做,通常Struts框架会自动的从action mapping中创建action对象。

    这样就是让spring去管理这些bean

    原文地址:http://www.cnblogs.com/wanggangblog/p/3662820.html

  • 相关阅读:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Visual Studio断点调试, 无法监视变量, 提示无法计算表达式
    ASP.NET MVC中MaxLength特性设置无效
    项目从.NET 4.5迁移到.NET 4.0遇到的问题
    发布网站时应该把debug设置false
    什么时候用var关键字
    扩展方法略好于帮助方法
    在基类构造器中调用虚方法需谨慎
    ASP.NET MVC中商品模块小样
    ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积02, 在界面实现
  • 原文地址:https://www.cnblogs.com/springwind2006/p/7555195.html
Copyright © 2011-2022 走看看