锁定老帖子 主题:Struts2源码分析讨论
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-12-26
其中有一处也觉的是比较关键的一步: 以下是DefaultActionInvocation中的invoke()方法的源码: public String invoke() throws Exception { String profileKey = "invoke: "; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException("Action has already executed"); } if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); return null; } }); } else { resultCode = invokeActionOnly(); } // this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) { if (preResultListeners != null) { for (Iterator iterator = preResultListeners.iterator(); iterator.hasNext();) { PreResultListener listener = (PreResultListener) iterator.next(); String _profileKey="preResultListener: "; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we're supposed to if (proxy.getExecuteResult()) { executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } } 不明白是怎样迭代执行一个又一个的Interceptor中的intercept方法. 按照我的理解,至少我可以看到一个循环遍厉interceptors这个集合才对. 大家可以讨论讨论,有知道的也可以告诉我.谢谢. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-12-26
这个嘛,你在找个Interceptor看看,你会发现它调用了这个invoke(),这个好像叫递归吧,说错了当没说啊(偶水平也很差啊)
|
|
返回顶楼 | |
发表时间:2007-12-27
恩,果然是这样.终于搞清楚了整个流程.较struts1而言,struts2的设计真是巧妙加精华.如果大家有什么关于struts2源码的问题,也可以发出来大家讨论.希望可以给大家帮助.
|
|
返回顶楼 | |
发表时间:2008-03-21
你好,想请教下,怎么在自定义的拦截器中得请求参数的值呢?
|
|
返回顶楼 | |
发表时间:2008-03-21
能否整个流程给讲解一下
|
|
返回顶楼 | |
发表时间:2008-03-28
从代码上看感觉有点象是回调加上递归具体分析如下
DefaultActionInvocation.invoke方法 if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); return null; } }); } else { resultCode = invokeActionOnly(); }
相应的interceptor中的处理如下 public String intercept(ActionInvocation invocation) throws Exception { //aciton方法执行前拦截器的处理的代码 //调用下一个拦截器或者action的execute方法. invocation.invoke(); //action的execute方法调用完毕,并且执行完了preresultlistener和result. //action方法执行后的拦截器处理的代码 return result; } 由于该调用方法是类似递归方式的调用所以代码块执行顺序如struts文档中的描述. 假设有如下拦截器栈 <interceptor-stack name="xaStack"> <interceptor-ref name="thisWillRunFirstInterceptor"/> <interceptor-ref name="thisWillRunNextInterceptor"/> <interceptor-ref name="followedByThisInterceptor"/> <interceptor-ref name="thisWillRunLastInterceptor"/> </interceptor-stack> 那么执行的顺序如下 thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor 以上描述结合interceptor中的代码和递归的调用模式就能很好的理解了. |
|
返回顶楼 | |
发表时间:2008-03-28
DefaultActionInvocation 这个类我咋没找到呢??
|
|
返回顶楼 | |
发表时间:2008-03-28
hysoft 写道 DefaultActionInvocation 这个类我咋没找到呢??
这个类在xwork的源码中,需要去opensymphony网站上下载xwork的源码. |
|
返回顶楼 | |
发表时间:2008-03-29
myoldman,你下面这段好像说错了:
thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor 因为MyAction2是类型为chain的Result,即,它也是Result,所以所有的PreResultListener应该在MyAction2之前被执行,然后MyAction2作为另外一个Action Invoke周期被执行。 我认为过程如下: thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyPreResultListener thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor |
|
返回顶楼 | |
发表时间:2008-03-29
另外想说的是,这里面的递归真是有点怪。呵呵。
这不是常见的那种递归,即一个方法递归调用自身。 而是,这个方法调用一个Interceptor的方法,并把自身传进去,让Interceptor调回自身这个方法,然后再以同样的方式去调用另一个Interceptor……这样子递归。 另外有一个要注意的是executed这个成员变量。 通常情况下,如果Action被正常执行,那么Action返回的Result会被执行,并把这个executed设为true。如果过程中出错,有异常抛出,那么可能在这之前就没有Result被执行,而ExceptionMappingInterceptor把异常映射到某个Result,然后返回来,这时,因为executed还是false,所以这个用于处理异常的Result会被执行。 看清楚了这两点,上面的代码也就没什么了吧~^_^ |
|
返回顶楼 | |