1. 程式人生 > >struts2與spring整合時,關於class屬性及成員bean自動注入的問題

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"/&gt;,只要有<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配置檔案中的相對應的ActionbeanId的屬性保持一致,系統即可通過Spring來裝配和管理Action如果action包含了Service層的物件:

private StudentInfoServiceImpl studentInfoService;

則需要新增set方法,才可以使用Spring依賴注入:

public void setStudentInfoService(StudentInfoServiceImpl studentInfoService) {

    this.studentInfoService = studentInfoService;

}

如果actionstruts.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>

Struts2Spring整合的方案二:

前面兩個步驟和方案一的一樣;在配置struts.xml檔案時,Actionclass為該Action的類路徑,而在applicationContext.xml配置檔案中不需要新增Actionbean配置。這樣,當我們使用Action類時,由於studentInfoService已經配置了相關的bean,所以會自動裝配,並且action依然由spring進行例項化。

studentInfoService的配置:

<bean id="studentInfoService" class="com.exam.service.StudentInfoServiceImpl">

    <constructor-arg>

        <ref bean="studentInfoDAO" />

    </constructor-arg>

</bean>

重點studentInfoService和action中的屬性要一樣!!

Actionstruts.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>