spring和struts2整合詳解
首先,我們要了解,web.xml中的各種元素在web容器中的載入順序:listener(監聽器)>filter(過濾器)>servlet.
在web.xml中配置如下:
前面我們說到:listener的啟動優先順序要大於filter,因為spring和struts2結合時,spring作為一個管理和組裝物件的角色,就必需優先載入,然後再生產物件後對struts2的action進行注入,所以,這就是我們一般用listener啟動spring的原因。其實spring還可以交給struts2來啟動,通過修改struts2org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>f</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>f</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
類的init方法,來產生spring的webApplicationContext物件,但這樣spring就依賴於struts2了,這不是我們希望看到的。
對於<context-param>節點:
web容器為每個專案都會對應一個servletConfig物件,這個物件類似與專案中的Applcation物件,都是整個專案的全域性物件,看原始碼會發現,spring通過listener載入時在ContextLoader中,將spring的webApplication物件放置到了servletConfig(實際是放到servletContext中,這裡的servletContext代表的是全域性的上下文)中,這樣就可以在專案的任意能得到servletConfig物件的地方得到spring物件來讀取spring的bean了。
而<context-param>節點就是用來為這個全域性物件配置引數的,這樣就可以在整個專案中都能使用,spring就是通過servletConfig來讀取web.xml中的路徑引數來過得beans.xml等一些spring的xml檔案的。而
<param-value>classpath:beans.xml</param-value>
中,為什麼這樣寫,是spring的規範,spring認為當得到classpath:這樣的值時就認為這是一個檔案,會在當前專案中尋找此檔案並解析,當然,也可以給路徑,例如:/WEB-INF/classes/beans.xml。
以上是web.xml的配置,配置完成後,接下來就是配置struts.xml,很簡單,首先要在struts.xml中配置一個常量: <constant name="struts.objectFactory" value="spring" />.其實,在你匯入了struts-spring-plugin-xx-xx.jar的包後,這個常量已經在這個包中設定好了,所以上面的常量配不配,都沒有關係,這裡,我們顯式配置一下,當你沒有匯入spring的外掛包,上面的常量值是 struts2本身的一個objectFactory的一個類。
配置Action時,很簡單,只要將action的class替換為成在spring中的action類的id值就行了,因為,你的struts.objectFactory設定的時spring時,當你訪問一個action時,spring會通過action對應的name找到class,再用這個class到spring中找到id為class的值的類,然後生產出action.
spring和struts2零配置整合(在這裡,我用spring是xml方式,struts2用零配置方式):
零配置無非是將xml的配置方式,變成註解的方式,首先個人看法是,用註解維護起來沒有xml方便,個人比較傾向與xml配置。
我們知道,用註解配置action 是:@Action(value="/action"),但將註解和spring聯絡起來,我們看文件知道,只需要@Action(value="/action" className="spring中的ID"),這樣,當放問這個action時,struts2就向spring要action,spring則會通過這個className來匹配id,然後返回匹配的action類的例項。
經高人指導,還發現另一種配置方式:註解:@Action("/action"),action只需要這樣註解就行了,在spring那邊用這個action類的全名作為bean的id,我們知道,註解中,是不需要為action指定class這個屬性的,其實並不代表這個屬性不存在,這個屬性的值就是@Action所在的類名,當訪問沒有設定className屬性的action時,struts2找spring要Action,spring就通過這個action類的全名來匹配id的bean,所以,所以我們將這個bean的id設定為action的類名時,spring就能匹配到,這樣的配置方式使得spring和struts2解藕度就很高。
例如:
action的程式碼:
public class MyLoginAction {
private LoginVo lv = new LoginVo();
private MyUserService mus;
@Action(value="/mylogin")
public String login(){
System.out.println(lv.getUpwd()+"====="+lv.getUname());
mus.findUserByUnameUpwd(lv.getUname(), lv.getUpwd());
return null;
}
public MyUserService getMus() {
return mus;
}
public void setMus(MyUserService mus) {
this.mus = mus;
}
public LoginVo getLv() {
return lv;
}
public void setLv(LoginVo lv) {
this.lv = lv;
}
}
spring的xml配置檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="false">
<bean id="mdao" class="org.xuliang.dao.MyUserDao">
</bean>
<bean id="mservice" class="org.xuliang.services.MyUserService">
<property name="mud" ref="mdao" />
</bean>
<bean id="org.xuliang.web.actions.MyLoginAction" class="org.xuliang.web.actions.MyLoginAction">
</bean>
</beans>