細談Spring(十一)深刻理解spring+struts2整合(附源碼)

  Springstruts2是咱們在項目架構中用的比較多的兩個框架,怎麼才能把這兩個框架用好,怎麼來整合是咱們掌握運用這兩個框架的關鍵點,下面咱們就怎麼來整合,從哪來整合,爲何要整合,從這幾點來看一下struts2spring整合。下面咱們來具體分析一下: html


      咱們一塊兒來想一想,若是讓springstruts2進行整合,咱們就但願咱們能夠在spring中直接注入actionspring容器初始化的時候就給咱們建好了action,可是事情不像咱們想象的那麼簡單,由於struts2action是由struts2本身new出來的,他不受spring的管理,因此沒法自動注入。因此strutsspring整合的結合點在於,struts2action不能直接入service。好了,既然有了問題,spring或者struts2確定已經爲咱們把這個問題解決了。struts2解決這個問題是他給咱們提供了一個struts-spring-plugin的插件,經過這個插件咱們就能夠把咱們的struts2和是spring進行整合了。struts-spring-plugin將會對咱們的action進行管理,當spring須要action的時候他就能夠向struts-spring-plugin來要了。 java


源碼下載:用力點 node


下面咱們就具體的來看一下struts+spring整合過程 mysql


1.須要的jar包列表Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2


jar包名稱 web

所在位置 spring

說明 sql

antlr-2.7.6.jar apache

hibernate/lib/required api

解析HQL 服務器

aspectjrt

spring/lib/aspectj

AOP

aspectjweaver

..

AOP

cglib-nodep-2.1_3.jar

spring/lib/cglib

代理,二進制加強

common-annotations.jar

spring/lib/j2ee

@Resource

commons-collections-3.1.jar

hibernate/lib/required

集合框架

commons-fileupload-1.2.1.jar

struts/lib

struts

commons-io-1.3.2

struts/lib

struts

commons-logging-1.1.1

單獨下載,刪除1.0.4(struts/lib)

struts

spring

dom4j-1.6.1.jar

hibernate/required

解析xml

ejb3-persistence

hibernate-annotation/lib

@Entity

freemarker-2.3.13

struts/lib

struts

hibernate3.jar

hibernate

hibernate-annotations

hibernate-annotation/

hibernate-common-annotations

hibernate-annotation/lib

javassist-3.9.0.GA.jar

hiberante/lib/required

hibernate

jta-1.1.jar

..

hibernate transaction

junit4.5

mysql-

ognl-2.6.11.jar

struts/lib

slf4j-api-1.5.8.jar

hibernate/lib/required

hibernate-log

slf4j-nop-1.5.8.jar

hibernate/lib/required

spring.jar

spring/dist

struts2-core-2.1.6.jar

struts/lib

xwork-2.1.2.jar

struts/lib

struts2

commons-dbcp

spring/lib/jarkata-commons

commons-pool.jar

..

struts2-spring-plugin-2.1.6.jar

struts/lib



2.配置好jar包之後,若是咱們想在服務器一啓動就可讓spring容器自動去加載咱們在配置文件中配置的bean,那麼咱們要在web.xml中去配置一個監聽器,這個監聽器的做用是監聽咱們的application,一旦咱們的項目啓動就觸發了監聽器,咱們來看一下這個監聽器的配置:


<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<!-- default: /WEB-INF/applicationContext.xml -->
</listener>


若是你的配置文件不想放在默認的位置,而是本身去指定位置,那麼咱們將要在web.xml中再次配置以下:


<context-param>
<param-name>contextConfigLocation</param-name>
//這種配置能夠指定多個配置文件,由於spring的配置文件能夠分開寫成好幾個
<!-- <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>  -->
//指定spring配置文件的位置classpath下的beans.xml
<param-value>classpath:beans.xml</param-value>
</context-param>


      加載完上面的bean以後,咱們就要考慮去管理咱們的action了,咱們應該讓spring去找struts去要相應的action,把action實例化爲響應的bean,這時咱們就須要咱們上邊所提到的struts-spring-plugin這個jar包了。加上這個jar包以後咱們就可讓spring來管理咱們的action了。在struts-spring-plugin中有一個struts--pluginXml文件。下面咱們來看一下這個文件中的配置執行的具體過程


<struts>
    <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" />
    <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>


      關鍵是這個  <constant name="struts.objectFactory" value="spring" />這句配置就指明瞭咱們產生struts對象的工廠交給spring來產生咱們來看一下具體步驟:


struts2一塊兒動就會去加載配置文件,其中包括strutspluginxml讀取順序:

struts的讀常量:

struts-default.xml 

struts-plugin.xml

struts.xml

struts.properties

web.xml


       struts-plugin.xml指明瞭咱們產生對象的工廠交給spring來完成,執行到web.xml時,因爲spring容器的監聽器,這時spring容器就開始啓動,spring啓動以後會web.xml去找相應的配置,在web.xml中能夠找到spring中的配置文件beans.xml,而後去初始化全部的bean

       spring去加載beans.xml的時候會自動把全部的bean初始化,而且放在本身的容器裏。與此同時,struts2也有本身的bean容器,這個容器是strutsplugin提供的,他會把全部的action加載都加載到本身的容器裏而後根據action的屬性名字自動去spring去找名字和action屬性相同的bean直接注入到action,也就是說。咱們在action中其實不用配置注入的東西,struts容器會自動給咱們注入。但仍是要提供相應的setget方法。而且名字要約定好,action屬性和spring中的beanid要同樣。但不要忘記,actionscope設置成prototype


下面咱們來看一下具體的示例代碼:

package com.bzu.action;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.bzu.entity.Student;
import com.bzu.service.StudentService;
import com.opensymphony.xwork2.ActionSupport;
public class StudentAction extends ActionSupport {
private Student student;
private StudentService service;
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
service.login(student);
return SUCCESS;
}
public StudentService getService() {
return service;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public void setService(StudentService service) {
this.service = service;
}
//public static void main(String[] args) {
//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
//"beans.xml");
//
//StudentAction action = (StudentAction) context.getBean("StudentAction");
//
//System.out.println(action == null);
//
//StudentService ser = action.getService();
//
//ser.login(new Student("ss", "ss"));
//
//}


      須要注意的是,springstruts2整合的時候有一個屬性struts.objectFactory.spring.autoware,也就是說是struts屬性的的自動裝配類型,他的默認值是name,也就是說struts中的action中的屬性不須要配置,他默認的去beans.xml中去找名字相同的,應該注意的是,在給一些屬性起名字的時候不要和spring中配置的actionname屬性相同,不然會報異常


下面咱們來看一下struts.xmlbeans.xml的相關配置:

Struts.xml:


<struts>
<package name="registration" extends="struts-default">
<action name="StudentAction" class="com.bzu.action.StudentAction">
<result name="success">/Success.jsp</result>
<result name="fail">/Fail.jsp</result>
</action>
</package>
</struts>


Beans.xml

<bean id="stuDao" class="com.bzu.dao.impl.StudentDaoImpl"></bean>
<bean id="service" class="com.bzu.service.impl.StudentServiceImpl">
<property name="dao" ref="stuDao"></property>
</bean>
<!--這裏徹底能夠不寫-->
<!--
<bean id="StudentAction" class="com.bzu.action.StudentAction" scope="prototype">
<property name="service" ref="service"></property>
</bean>
-->


      上面的示例是用的struts2的容器來產生actionspring須要的時候要去struts容器裏面去找action,而後再初始化bean,其實咱們還有一種方法產生action,那就是讓spring容器去幫咱們來產生action,這樣咱們產生action的時候就能夠去spring容器裏面去找了,具體應該是在spring配置文件beans.xml中把對應的action配置成bean,而後再struts.xml中配置action的時候,action對應的class就再也不是配置成該action對應的類了,而是配置這個action對應的spring容器的beanid屬性,這樣action初始化的時候就會去spring容器裏面去找了。可是這樣配置的話,咱們的action屬性就必須配置了,由於spring來產生action後,struts容器就不會在自動去給咱們注入屬性了。若是不配置屬性的話會產生異常,下面咱們來看一下具體配置狀況:

Action的代碼仍是之前的代碼,沒有改變,這裏就再也不重複寫了,下面咱們來看一下struts.xml的配置:

Struts.xml

<struts>
<package name="registration" extends="struts-default">
<action name="StudentAction"  class="stuAction">
<result name="success">/Success.jsp</result>
<result name="fail">/Fail.jsp</result>
</action>
</package>
</struts>


上面的class對應的是下面actionbeanid屬性

Beans.xml

<bean id="stuDao" class="com.bzu.dao.impl.StudentDaoImpl"></bean>
<bean id="service" class="com.bzu.service.impl.StudentServiceImpl">
<property name="dao" ref="stuDao"></property>
</bean>
<!--如今這裏必須寫了,不寫會報錯-->
<bean id="stuAction" class="com.bzu.action.StudentAction" scope="prototype">
<property name="service" ref="service"></property>
</bean>




         OKstruts2+spring整合講到這就基本完了,固然我說的也不是很全面,但願你們見諒,但願你們能提出寶貴意見

相關文章
相關標籤/搜索