隨筆-60  評(píng)論-138  文章-1  trackbacks-0
          大約在08年年初的時(shí)候就知道igenko這個(gè)項(xiàng)目的存在,那個(gè)時(shí)候,還是剛剛起步,不過(guò)更新速度很快。
          之所以關(guān)注這個(gè)項(xiàng)目是因?yàn)榧夹g(shù)架構(gòu)和springside有很大的互補(bǔ)的地方,兩者都使用了spring,但是springside很著重展示后臺(tái)部分(當(dāng)然了,這個(gè)隨著小胖的加入,前臺(tái)的grid會(huì)更強(qiáng)),而igenko則是更加著重前臺(tái)展現(xiàn)(它使用了flex作為客戶端)。另外,igenko值得關(guān)注的原因還有,他使用了jbpm作為工作流,并且項(xiàng)目的目標(biāo)很明確,一個(gè)基于ria展現(xiàn)的cms系統(tǒng)。

          本篇關(guān)注一下igenko的客戶端登陸邏輯。
          對(duì)于登陸的后臺(tái)部分邏輯是使用的spring-acegi,所以后臺(tái)的部分和springside非常的相似,如果誰(shuí)覺(jué)得需要更多了解,直接去看springside的wiki是最省事的了。而前臺(tái)的邏輯中,igenko試用了puremvc作為其mvc的框架,更有意思的是,bouiaw找了一個(gè)prana的開源框架充來(lái)當(dāng)spring的角色,完成ioc的注入。
          在puremvc的邏輯中,需要在view(也就是mxml中)觸發(fā)出事件,而Mediator(view的一部分,相當(dāng)于view的邏輯部分)來(lái)監(jiān)聽這個(gè)事件。繼而Mediator將會(huì)發(fā)出Notify。系統(tǒng)中其他地方接收這個(gè)通知,繼而進(jìn)行相關(guān)的邏輯處理,也就是說(shuō),view層的Mediator發(fā)送了消息給controll,繼而view層退出這個(gè)事件了處理。
          上邊的邏輯大家可以在,org.igenko.client.backoffice.view.common.BackofficeLogin這個(gè)類中看到,這個(gè)類觸發(fā)了一下的事件:
          dispatchEvent( new Event( BackofficeLogin.LOGIN ) );
          而org.igenko.client.backoffice.view.common.mediator.BackofficeLoginMediator則監(jiān)聽這個(gè)事件,如下:
          backofficeLogin.addEventListener( BackofficeLogin.LOGIN, login );
          繼而在login方法中,處理邏輯:
          1 private function login( event:Event ) : void
          2         {
          3             sendNotification(NotificationConstants.LOGIN, new User(backofficeLogin.username.text, backofficeLogin.password.text));    
          4         }
          這個(gè)當(dāng)中就發(fā)送了我說(shuō)的那個(gè)通知。接下來(lái)就是controll層來(lái)處理這個(gè)通知。
          而controll層就是puremvc中的commond,按著文檔中的邏輯,那個(gè)通知觸發(fā)那個(gè)commond是由facade這個(gè)接口來(lái)負(fù)責(zé)的。
          這個(gè)時(shí)候就是igenko的一個(gè)有意思的地方了。在puremvc的文檔中,應(yīng)該在facade當(dāng)中將commond注冊(cè)進(jìn)去,但是ingeko只是
          override protected function initializeController():void
                  {
                      
          super.initializeController();
                      
                      registerCommand(NotificationConstants.SERVICE_ERROR, ShowServiceError);
                      registerCommandByConfigName(NotificationConstants.STARTUP, NotificationConstants.STARTUP_CMD);
                      
                  }
          當(dāng)中看似沒(méi)有注冊(cè)任何關(guān)于Login的commond,但是當(dāng)關(guān)注到NotificationConstants.STARTUP_CMD這個(gè)commond的時(shí)候,就會(huì)發(fā)現(xiàn)如下的代碼:
           public function set commands(_commands:Array):void {
                       logger.debug(
          "entering set commands");
                      
          for each ( var c : Object in _commands ) {
                          var commandInstance:IIocCommand 
          = c as IIocCommand;             
                              logger.debug(
          "addSubCommand " + commandInstance);
                              addSubCommand(commandInstance);
                          }   
                    }
          這說(shuō)明,facade加入了一個(gè)StartupCommand,而StartupCommand又繼承了IocManagedMacroCommand這個(gè)可以執(zhí)行多個(gè)commond的類,那么就是相當(dāng)于facade注冊(cè)很多個(gè)commond.
          接下來(lái)的問(wèn)題就是,StartupCommand中的_commands這個(gè)數(shù)組是那里來(lái)的呢?
          答案就是,ioc注入的。
          在ApplicationContextCommon.xml中可以發(fā)現(xiàn)如下的配置:
          <object id="startupCommand" class="org.igenko.client.common.controller.StartupCommand">
                   
          <property name="commands">
                       
          <array>
                           
          <ref>registerCommandsCommand</ref>
                           
          <ref>registerProxiesCommand</ref>
                           
          <ref>registerMediatorsCommand</ref>
                       
          </array>
                   
          </property>
              
          </object>
          對(duì)于當(dāng)中的registerCommandsCommand是如下的:
          <object id="registerCommandsCommand" class="org.igenko.client.common.controller.startup.RegisterCommandsCommand">
                 
          <property name="commands">
                       
          <array>
                             
          <!-- Login commands -->
                             
          <object class="org.igenko.client.common.controller.DynamicObject">
                             
          <property name="notification">
                                
          <object class="org.pranaframework.ioc.factory.config.FieldRetrievingFactoryObject">
                                     
          <property name="staticField" value="org.igenko.client.common.NotificationConstants.LOGIN"/>
                                
          </object>
                             
          </property>
                             
          <property name="command" ref="loginCommand" />
                          
          </object>
                          
                          
          <object class="org.igenko.client.common.controller.DynamicObject">
                             
          <property name="notification">
                                
          <object class="org.pranaframework.ioc.factory.config.FieldRetrievingFactoryObject">
                                     
          <property name="staticField" value="org.igenko.client.common.NotificationConstants.LOGOUT"/>
                                
          </object>
                             
          </property>
                             
          <property name="command" ref="logoutCommand" />
                          
          </object> 
                                    
                          
          <!-- Webcompiler commands -->
                            
          <object class="org.igenko.client.common.controller.DynamicObject">
                             
          <property name="notification">
                                
          <object class="org.pranaframework.ioc.factory.config.FieldRetrievingFactoryObject">
                                     
          <property name="staticField" value="org.igenko.client.common.NotificationConstants.COMPILE_WIDGET"/>
                                
          </object>
                             
          </property>
                             
          <property name="command" ref="compileWidgetCommand" />
                          
          </object>
                    
                        
          </array>
                    
          </property>
              
          </object>

          可以看見第一個(gè)注入的就是loginCommand.

          繼而,我們可以看見經(jīng)過(guò)一系列的尋找,觸發(fā)了view層的login事件,最后會(huì)到達(dá)到
          org.igenko.client.common.controller.login.LoginCommand類的excute方法(很類似struts1吧,連方法名都一致)。如下:
          override public function execute(notification:INotification):void
                  {    
                      userToLogin 
          = notification.getBody() as User ;
                      
          // inserted via IoC
                      ILoginDelegate(delegate).checkLogin(userToLogin.name, userToLogin.password);
                  }

          接下來(lái)就是通過(guò)remote object與后端通信了。

          希望這個(gè)摘記對(duì)于剛剛接觸的人有幫助。對(duì)于文中的不合理之處,歡迎指出!

          posted on 2008-10-08 10:13 張氏兄弟 閱讀(1993) 評(píng)論(0)  編輯  收藏 所屬分類: flex
          主站蜘蛛池模板: 安塞县| 栖霞市| 大邑县| 高陵县| 达州市| 康保县| 中山市| 朝阳区| 东安县| 景谷| 丰镇市| 鹤峰县| 鄯善县| 蓬莱市| 福建省| 花垣县| 叙永县| 武城县| 成都市| 乐陵市| 佳木斯市| 乐安县| 金山区| 五家渠市| 调兵山市| 吴川市| 大石桥市| 原阳县| 通渭县| 城口县| 赤峰市| 根河市| 望江县| 喀什市| 浦江县| 大丰市| 盐城市| 横峰县| 高青县| 绥棱县| 厦门市|