Spring和struts2是咱們在項目架構中用的比較多的兩個框架,怎麼才能把這兩個框架用好,怎麼來整合是咱們掌握運用這兩個框架的關鍵點,下面咱們就怎麼來整合,從哪來整合,爲何要整合,從這幾點來看一下struts2和spring的整合。下面咱們來具體分析一下: html
咱們一塊兒來想一想,若是讓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來要了。 java
源碼下載:用力點 node
下面咱們就具體的來看一下struts+spring的整合過程: mysql
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 |
|
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 |
|
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
<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>
OK,struts2+spring整合講到這就基本完了,固然我說的也不是很全面,但願你們見諒,但願你們能提出寶貴意見