struts2-spring-plugin.jar的作用

本文轉載自:http://md20040208.blog.163.com/blog/static/3006942720107208164038/

struts2-spring-plugin.jar的一些感悟  

2010-08-20 20:38:55|  分類: S2SH|字號 訂閱

         在我們集成struts2+spring+hibernate,也就是所謂的S2SH,不可避免的要引入struts2-spring-plugin.jar插件。當引入這個插件後,原先所struts創建的action類,交給了spring創建。在struts2-spring-plugin.jar中有一個struts-plugin.xml,裏面聲明瞭action類由spring工廠創建。在struts2插件文檔裏,這樣寫着“The Spring Plugin works by overriding the Struts ObjectFactory to enhance the creation of core framework objects”這個插件重寫了struts的對象工廠,當創建一個action類時,它會根據struts的配置文件的class屬性的值與spring配置文件中的id屬性的值相匹配。如果沒有與之相匹配,將會像沒有使用這個插件前一樣創建,然後由spring自動裝配。

         那時我有些不是很明白,爲什麼我的action類沒有寫註解@Component("xxAction"),還是可以被spring自動裝配。那是因爲action類被struts和struts2-spring-plugin創建,再由spring自動裝配,但不由spring管理。如果我們想使用spring複雜的aop或spring其他的功能時,強烈建議將acion類註冊到spring容器中。

         今天,再次做測試,又有了出乎意料的結果。在此說明,我的測試中用的是annotion註解,不是xml文件。

         之前,我們說過,當創建一個action類時,它會根據struts的配置文件的class屬性的值與spring配置文件中的id屬性的值相匹配。如果沒有與之相匹配,將會像沒有使用這個插件前一樣創建,然後由spring自動裝配。這兩種情況會出現不同的結果。現在我們慢慢來說明。

          假設我們有一個AddUserAction的類,位於com.action包下,它有屬性userService:

          package com.action;

          import com.opensymphony.xwork2.ActionSupport;
          import com.service.UserService;

         public class AddUserAction extends ActionSupport {

          private UserService userService;

          public void setUserService(UserService userService) {
                         this.userService = userService;
          }

         @Override
         public String execute() throws Exception {
                  System.out.println(userService==null);  
                  return SUCCESS;
        }

 }

       以上這個類是我們最簡單的action類,在沒有引入struts2-spring-plugin.jar插件時,action類是由struts創建的,我們struts.xml文件是這樣寫的:

<struts>

        <package name="registration" extends="struts-default">
                <action name="addUser" class="com.action.AddUserAction">
                       <result>success.jsp</result>
               </action>
        </package>

</struts>

     但如果我們引入struts2-spring-plugin.jar插件後,如果我們的struts.xml文件還是如同以上一樣寫,就會出現struts的配置文件的class屬性的值與spring配置文件中的id屬性的值不匹配,因爲action類沒有註冊到spring的容器中。那action的創建由strutst和struts2-spring-plugin.jar插件創建,默認地根據名字到spring容器中去找相應的對象進行自動裝配(不管你是否願意,只要提供了set方法),所以userService不會是null值,這個action類的scope也默認的是prototype,但這個action類不在spring容器中

    自然的,以上這種情況不是我們想要的,因爲很多情況都不在我們的控制範圍內。那隻要我們將action類的創建交給spring,就可以自主也配置我們想要的屬性。這時我們將原來的action類改爲:

        package com.action;

        mport javax.annotation.Resource;

        import org.springframework.context.annotation.Scope;
        import org.springframework.stereotype.Component;

        import com.opensymphony.xwork2.ActionSupport;
        import com.service.UserService;

       @Component("addUserAction")
       @Scope("prototype")
        public class AddUserAction extends ActionSupport {

                private UserService userService;

               @Resource(name="userService")
               public void setUserService(UserService userService) {
                       this.userService = userService;
              }

       @Override
       public String execute() throws Exception {
              System.out.println(userService==null);  
              return SUCCESS;
       }
}

        在第二個action類中,我們加入了相應的annotion,把我們的action類註冊到spring容器中。我們的struts.xml文件也改爲:

<struts>

        <package name="registration" extends="struts-default">
                <action name="addUser" class="addUserAction">
                       <result>success.jsp</result>
               </action>
        </package>

</struts>

       這時,struts的配置文件的class屬性的值與spring配置文件中的id屬性的值匹配。如果我們不想裝配userService,可以將@Resource(name="userService")刪除。

       所以,在struts.xml裏的class的屬性值決定你以那種方式創建action類,我個人傾向於將action類交給spring管理和自動裝配。

       如果有什麼不正確的地方,歡迎大家指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章