上篇博客介紹了Struts1.X與Spring集成的一種方案。 Struts1.X與Spring集成——第一種方案
此篇博客還以上篇博客的登錄例子爲例,介紹Struts1.X與Spring集成的另一種方案。
1,第一種方案 原理
回憶第一種方案集成原理:在Action中取得BeanFactory,通過BeanFactory取得業務邏輯對象
此種方案的缺點:從嚴格意義的分層上來看,Action上看到了Spring的相關東西,依賴Spring API去查找東西,發生了依賴查找,因爲要查找依賴對象,所以要依賴Spring服務才能找到,因爲在Spring提供的工廠裏。應該是Action中看不到Spring相關東西,Action中看到的就是業務接口,這樣的話層次更加分明。
2,第二種方案 原理
基於第一種方案的缺點,我們改成不在去查找業務對象,讓IOC注入進來,只要提供setter方法,就能把對象主動傳過來——依賴注入(侷限性:在同一個JVM裏可以,跨JVM不可以依賴注入)
如果想被Spring注入,Action需要被Spring管理,也就是說LoginAction的創建是從IOC容器中創建出來的,而不應該再是讓Struts創建。如果還是Struts創建的話,UserManager是不可能注入進來的。只有從IOC容器中拿出來的東西,所有的依賴關係才被注入,所以Action必須被Spring管理,被Spring管理,就需要配置到Spring的配置文件中。
applicationContext-beans.xml:
applicationContext-action.xml:
只要通過BeanFactory getBean()把"LoginAction"拿到,同時userManager的依賴關係都會注入進去;
3,分析第二種方案提出的原由
第一種方案:
Web客戶端發出請求,請求ActionServlet,Struts流程是在Struts裏面要查看Struts-config.xml,把LoginAction拿出來new,如下:
Struts進行new,只會new LoginAction,其他的UserManager不會new,也不會注入。
所以此種流程是不行的,依賴對象不能注入。
但是,用Struts的話必須得請求Action,所以需要使用Spring,Spring實現了一個Action(Action代理類:ActionProxy)——不會改變原先Action的相關接口,只是代理,代理可以控制原目標,在調目標之前可以做些事情。所以Struts-config.xml文件中就不應該配置LoginAction.java這個類了,要配置Spring給提供的一個類,它提供的類起到了什麼作用:web客戶端發出請求,需要Struts把Spring提供的代理類new出,這個代理類中負責拿到BeanFactory,通過getBean(),把這次請求對應的Action拿出來(是從IOC容器中拿出LoginAction),那麼它的依賴對象就都會被注入。如下圖第二種方案:
第二種方案:
將第一種方案,Struts-config.xml中配置的LoginAction.Java類(如下圖(1))改爲配置org.springframework.web.struts.DelegatingActionProxy.class(2)
(1)
(2)
(3)
applicationContext-action.xml:配置LoginAction類,來管理LoginAction類
一個請求過來,Struts中new出代理類DelegatingActionProxy,通過代理類調用getBean(beanName,Action.Class)方法,將path的名稱"/login"傳入,到IOC中找到對應name的Action(即,LoginAction類(在applicationContext-action.xml中配置過了,如圖(3)))
第二種方案集成原理:Struts的Action交給Spring創建;
將業務邏輯對象通過spring注入到Action中,從而避免了在Action類中的直接代碼查詢
(客戶端請求---->代理action--->取得BeanFactory--->getBean(..)創建action示例--->執行exctute方法)
4,代碼示例
簡單登錄例子
只是Spring配置文件和Struts配置文件,以及LoginAction.java有所變動,其他代碼參考 Struts1.X與Spring集成——第一種方案
struts-config.xml配置文件:配置代理Action及ActionForm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<!--生命ActionForm(即,告訴Struts哪個是ActionForm) -->
<form-beans>
<form-bean name="loginForm" type="com.bjpowernode.usermgr.web.forms.loginActionForm"/>
</form-beans>
<!-- 描述Action -->
<!-- 描述Action -->
<action-mappings>
<action path="/login"
type="org.springframework.web.struts.DelegatingActionProxy"
name="loginForm"
scope="request">
<!-- 轉向信息 -->
<forward name="success" path="/login_success.jsp"/>
</action>
</action-mappings>
<message-resources parameter="MessageResources" />
</struts-config>
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 這個IOC容器核心是個工廠,抽象工廠 -->
<bean id="userManager" class="com.bjpowernode.usermgr.manager.UserMangerImpl"/>
</beans>
applicationContext-action.xml配置文件:配置Struts的Action
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 配置Struts的Action -->
<bean name="/login" class="com.bjpowernode.usermgr.web.actions.LoginAction" scope="prototype">
<property name="userManager" ref="userManager"/>
</bean>
</beans>
5,運行
6,總結