Spring整合Struts的两种方式介绍

1 使用Spring托管Struts Action

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

<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配置文件中加入以下配置:spring

<struts>

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

</struts>

 

而Spring的配置文件中有以下配置:apache

<!--配置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,表示每次请求都会产生一个新的实例。session

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

<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只是负责装配。jsp

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

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

 

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

<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。prototype

 

3   方式一、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

相关文章
相关标签/搜索