Spring和struts2是我們在項目架構中用的比較多的兩個框架,,怎么才能把這兩個框架用好,怎么來整合是我們掌握運用這兩個框架的關鍵點,,下面我們就怎么來整合,,從哪來整合,為什么要整合,,從這幾點來看一下struts2和spring的整合,。下面我們來具體分析一下:
我們一起來想想,如果讓spring和struts2進行整合,,我們就希望我們可以在spring中直接注入action,,spring容器初始化的時候就給我們建好了action,但是事情不像我們想象的那么簡單,,因為struts2的action是由struts2自己new出來的,,他不受spring的管理,所以無法自動注入,。所以struts和spring的整合的結(jié)合點在于,,struts2的action不能直接入service。好了,,既然有了問題,,spring或者struts2肯定已經(jīng)為我們把這個問題解決了。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中去配置一個監(jiān)聽器,,這個監(jiān)聽器的作用是監(jiān)聽我們的application,,一旦我們的項目啟動就觸發(fā)了監(jiān)聽器,我們來看一下這個監(jiān)聽器的配置:
- <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文件,。下面我們來看一下這個文件中的配置執(zhí)行的具體過程:
- <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" />,,這句配置就指明了我們產(chǎn)生struts對象的工廠交給spring來產(chǎn)生,我們來看一下具體步驟:
struts2一起動就會去加載配置文件,,其中包括struts—plugin,。xml讀取順序:
struts的讀常量:
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml
struts-plugin.xml指明了我們產(chǎn)生對象的工廠交給spring來完成,當執(zhí)行到web.xml時,,由于spring容器的監(jiān)聽器,,這時spring容器就開始啟動,spring啟動之后會web.xml去找相應的配置,,在web.xml中可以找到spring中的配置文件beans.xml,,然后去初始化所有的bean。
spring去加載beans.xml的時候會自動把所有的bean初始化,,并且放在自己的容器里,。與此同時,struts2也有自己的bean容器,,這個容器是struts—plugin提供的,,他會把所有的action加載都加載到自己的容器里。然后根據(jù)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的容器來產(chǎn)生action,spring需要的時候要去struts容器里面去找action,然后再初始化bean,,其實我們還有一種方法產(chǎn)生action,,那就是讓spring容器去幫我們來產(chǎn)生action,這樣我們產(chǎn)生action的時候就可以去spring容器里面去找了,,具體應該是在spring配置文件beans.xml中把對應的action配置成bean,,然后再struts.xml中配置action的時候,action對應的class就不再是配置成該action對應的類了,,而是配置這個action對應的spring容器的bean的id屬性,,這樣action初始化的時候就會去spring容器里面去找了。但是這樣配置的話,,我們的action屬性就必須配置了,,因為spring來產(chǎn)生action后,struts容器就不會在自動去給我們注入屬性了,。如果不配置屬性的話會產(chǎn)生異常,,下面我們來看一下具體配置情況:
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>
- <!--現(xiàn)在這里必須寫了,不寫會報錯-->
- <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>
-
|