随笔-60  评论-138  文章-1  trackbacks-0
大约在08年年初的时候就知道igenko这个项目的存在,那个时候,还是刚刚起步,不过更新速度很快。
之所以关注这个项目是因为技术架构和springside有很大的互补的地方,两者都使用了spring,但是springside很着重展示后台部分(当然了,这个随着小胖的加入,前台的grid会更强),而igenko则是更加着重前台展现(它使用了flex作为客户端)。另外,igenko值得关注的原因还有,他使用了jbpm作为工作流,并且项目的目标很明确,一个基于ria展现的cms系统。

本篇关注一下igenko的客户端登陆逻辑。
对于登陆的后台部分逻辑是使用的spring-acegi,所以后台的部分和springside非常的相似,如果谁觉得需要更多了解,直接去看springside的wiki是最省事的了。而前台的逻辑中,igenko试用了puremvc作为其mvc的框架,更有意思的是,bouiaw找了一个prana的开源框架充来当spring的角色,完成ioc的注入。
在puremvc的逻辑中,需要在view(也就是mxml中)触发出事件,而Mediator(view的一部分,相当于view的逻辑部分)来监听这个事件。继而Mediator将会发出Notify。系统中其他地方接收这个通知,继而进行相关的逻辑处理,也就是说,view层的Mediator发送了消息给controll,继而view层退出这个事件了处理。
上边的逻辑大家可以在,org.igenko.client.backoffice.view.common.BackofficeLogin这个类中看到,这个类触发了一下的事件:
dispatchEvent( new Event( BackofficeLogin.LOGIN ) );
而org.igenko.client.backoffice.view.common.mediator.BackofficeLoginMediator则监听这个事件,如下:
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         }
这个当中就发送了我说的那个通知。接下来就是controll层来处理这个通知。
而controll层就是puremvc中的commond,按着文档中的逻辑,那个通知触发那个commond是由facade这个接口来负责的。
这个时候就是igenko的一个有意思的地方了。在puremvc的文档中,应该在facade当中将commond注册进去,但是ingeko只是
override protected function initializeController():void
        {
            
super.initializeController();
            
            registerCommand(NotificationConstants.SERVICE_ERROR, ShowServiceError);
            registerCommandByConfigName(NotificationConstants.STARTUP, NotificationConstants.STARTUP_CMD);
            
        }
当中看似没有注册任何关于Login的commond,但是当关注到NotificationConstants.STARTUP_CMD这个commond的时候,就会发现如下的代码:
 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);
                }   
          }
这说明,facade加入了一个StartupCommand,而StartupCommand又继承了IocManagedMacroCommand这个可以执行多个commond的类,那么就是相当于facade注册很多个commond.
接下来的问题就是,StartupCommand中的_commands这个数组是那里来的呢?
答案就是,ioc注入的。
在ApplicationContextCommon.xml中可以发现如下的配置:
<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>
对于当中的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>

可以看见第一个注入的就是loginCommand.

继而,我们可以看见经过一系列的寻找,触发了view层的login事件,最后会到达到
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);
        }

接下来就是通过remote object与后端通信了。

希望这个摘记对于刚刚接触的人有帮助。对于文中的不合理之处,欢迎指出!

posted on 2008-10-08 10:13 张氏兄弟 阅读(1979) 评论(0)  编辑  收藏 所属分类: flex

只有注册用户登录后才能发表评论。


网站导航: