struts2與spring集成時,關於class屬性及成員bean自動註入的問題
正常來說按照Spring官方配置,在struts2與spring整合時,struts配置文件中class屬性指向spring配置的bean id,但是在class指向類路徑時,依然能註入service。
public class LoginAction extends ActionSupport{ private LoginService loginService; public void setLoginService(LoginService loginService) { System.out.println("init Service......");this.loginService = loginService; }
spring配置
<bean id="loginService" class="org.xxxxx.services.impl.LoginServiceImpl"></bean> <bean id="loginAction" class="org.xxxxx.action.LoginAction"> </bean>
struts配置
<action name="login" class="org.xxxxx.action.LoginAction">
<result name="success">/result.jsp</result>
<result name="error">/login.jsp</result>
</action>
1.註意看以上兩個紅線部分,在struts.xml中action指定的class像上面這種方式指定全類路徑名的話,這時,不論spring配置文件中的<bean id="loginAction" class="org.xxxxx.action.LoginAction"></bean>有沒有指定配置<property name="loginService" ref="loginService",只要有<bean id="loginService" .../>存在,並且這個ID的名字與Action中成員bean的名字一致,當實例化Action類時,會一並將loginService的實例註入。
並且還存在一個問題當struts.xml此種方式配置時,spring中如果配置了此action實例,並添加scope=“prototype”多例屬性,則會在訪問時報錯。可能struts2本身是多例與spring實例化機制沖突。所以此種方式配置時,可廢棄spring中的action類配置。
2.如果<action name="login" class="loginAction">這裏的class指定spring配置文件中的bean的id,則不會出現loginService自動註入問題,而是根據<bean id="loginAction" class="org.xxxxx.action.LoginAction"></bean>有沒有指定配置<property name="loginService" ref="loginService"/>來決定,有<property name="loginService" ref="loginService"/>的指定,則實例化Action類時,會一並將loginService實例註入,沒有配置property,loginService則為空
所以會產生兩種struts與spring的配置方案:
(1)配置方案一:
在配置Action時,需要將class屬性和Spring配置文件中的相對應的Action的bean的Id的屬性保持一致,系統即可通過Spring來裝配和管理Action。
如果action包含了Service層的對象:
private StudentInfoServiceImpl studentInfoService;
則需要添加set方法,才可以使用Spring依賴註入:
public void setStudentInfoService(StudentInfoServiceImpl studentInfoService) {
this.studentInfoService = studentInfoService;
}
如果action在struts.xml如下配置:
<action name="studentRegister" class="studentRegisterAction"> <result name="result">/WEB-INF/exam/result.jsp </result> <result name="input">/WEB-INF/exam/error.jsp </result> <interceptor-ref name="excludeParamsStack" /> </action>
則在applicationContext.xml文件中該Action的配置如下:
<bean id="studentRegisterAction" class="com.exam.actions.StudentRegisterAction" scope="prototype"><!--指定多例-->
<property name="studentInfoService">
<ref bean="studentInfoService" />
</property>
</bean>
Struts2與Spring整合的方案二:
前面兩個步驟和方案一的一樣;
在配置struts.xml文件時,Action的class為該Action的類路徑,而在applicationContext.xml配置文件中不需要添加Action的bean配置。這樣,當我們使用Action類時,由於studentInfoService已經配置了相關的bean,所以會自動裝配,並且action依然由spring進行實例化。
studentInfoService的配置:
<bean id="studentInfoService" class="com.exam.service.StudentInfoServiceImpl">
<constructor-arg>
<ref bean="studentInfoDAO" />
</constructor-arg>
</bean>
重點studentInfoService和action中的屬性要一樣!!
Action在struts.xml中的配置如下:
<action name="studentRegister" class="com.exam.actions.StudentRegisterAction"><!--struts2 默認多例--> <result name="result">/WEB-INF/exam/result.jsp </result> <result name="input">/WEB-INF/exam/error.jsp </result> <interceptor-ref name="excludeParamsStack" /> </action>
struts2與spring集成時,關於class屬性及成員bean自動註入的問題