1. 程式人生 > >struts2如何跟spring整合的,原來是:struts2-spring-plugin.jar

struts2如何跟spring整合的,原來是:struts2-spring-plugin.jar

在我們整合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管理和自動裝配。

       如果有什麼不正確的地方,歡迎大家指出。 小結: @Component("addUserAction")和@Controller效果是一樣的,可換成@Controller,因為@Controller被spring自動裝配為“addUserAction”;@Resource(name="userService")                public void setUserService(UserService userService) {
                       this.userService = userService;
              } @Resource(name="userService")加上set()方法和 @Resource privateUserService userService ;是一樣的效果,@Resource被spring自動裝配為(name="userService")