Spring和struts2是我們在項目架構中用的比較多的兩個框架,怎麼才能把這兩個框架用好,怎麼來整合是我們掌握運用這兩個框架的關鍵點,下面我們就怎麼來整合,從哪來整合,爲什麼要整合,從這幾點來看一下struts2和spring的整合。下面我們來具體分析一下:
我們一起來想想,如果讓spring和struts2進行整合,我們就希望我們可以在spring中直接注入action,spring容器初始化的時候就給我們建好了action,但是事情不像我們想象的那麼簡單,因爲struts2的action是由struts2自己new出來的,他不受spring的管理,所以無法自動注入。所以struts和spring的整合的結合點在於,struts2的action不能直接入service。好了,既然有了問題,spring或者struts2肯定已經爲我們把這個問題解決了。struts2解決這個問題是他給我們提供了一個struts-spring-plugin的插件,通過這個插件我們就可以把我們的struts2和是spring進行整合了。struts-spring-plugin將會對我們的action進行管理,當spring需要action的時候他就可以向struts-spring-plugin來要了。
源碼下載:用力點
下面我們就具體的來看一下struts+spring的整合過程:
1.需要的jar包列表:Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2
jar包名稱 |
所在位置 |
說明 |
antlr-2.7.6.jar |
hibernate/lib/required |
解析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--plugin。Xml文件。下面我們來看一下這個文件中的配置執行的具體過程:
- <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一起動就會去加載配置文件,其中包括struts—plugin。xml讀取順序:
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容器,這個容器是struts—plugin提供的,他會把所有的action加載都加載到自己的容器裏。然後根據action的屬性名字自動去spring去找名字和action屬性相同的bean直接注入到action中,也就是說。我們在action中其實不用配置注入的東西,struts容器會自動給我們注入。但還是要提供相應的set、get方法。並且名字要約定好,action屬性和spring中的bean的id要一樣。但不要忘記,action的scope設置成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"));
- //
- //}
需要注意的是,spring和struts2整合的時候有一個屬性struts.objectFactory.spring.autoware,也就是說是struts屬性的的自動裝配類型,他的默認值是name,也就是說struts中的action中的屬性不需要配置,他默認的去beans.xml中去找名字相同的,應該注意的是,在給一些屬性起名字的時候不要和spring中配置的action的name屬性相同,否則會報異常
下面我們來看一下struts.xml和beans.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的容器來產生action,spring需要的時候要去struts容器裏面去找action,然後再初始化bean,其實我們還有一種方法產生action,那就是讓spring容器去幫我們來產生action,這樣我們產生action的時候就可以去spring容器裏面去找了,具體應該是在spring配置文件beans.xml中把對應的action配置成bean,然後再struts.xml中配置action的時候,action對應的class就不再是配置成該action對應的類了,而是配置這個action對應的spring容器的bean的id屬性,這樣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對應的是下面action中bean的id屬性
Beans.xml
- <pre name="code" class="html"><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></pre><br>
- <br>
- <pre></pre>
- <p></p>
- <pre></pre>
- <p></p>
- <p></p>
- <p></p>
- <p><span style="font-size:18px"> OK<span style="font-family:宋體">,</span><span style="font-family:Courier New">struts2+spring</span><span style="font-family:宋體">整合講到這就基本完了,當然我說的也不是很全面,希望大家見諒,希望大家能提出寶貴意見</span></span></p>
- <p></p>
- <pre></pre>
- <pre></pre>
- <div style="padding-top:20px">
- <p style="font-size:12px;">版權聲明:本文爲博主原創文章,未經博主允許不得轉載。</p>
- </div>