1.1.1       ActionInvocation类

ActionInvocation定义为一个接口。主要作用是表现action的运行状态。它拥有拦截器和action的实例。通过重复的运行invoke方法。首先被actionProxy,然后是拦截器,全部拦截器运行完后就是action和result .

图3.3.4 ActionInvocation类的主要方法

1.1.2       DefaultActionInvocation类

DefaultActionInvocation类是ActionInvocation接口的实现类. 一般都用该类实例化ActionInvocation。 基本的方法例如以下:

图3.3.5 DefaultActionInvocation类的主要方法

关键方法:invoke()方法

executed = false; 默觉得false。表示该action还没有运行。

假设运行就会抛出已经运行的异常。

然后推断拦截器是否已经配置,假设配置了拦截器就会从配置信息中获得拦截器配置类InterceptorMapping。

此类中仅仅包括两个属性,一个就是name和interceptor实例。

public String invoke()
throws
Exception {

String profileKey = "invoke: ";

try {

UtilTimerStack.push(profileKey);

if (executed) {

throw
new
IllegalStateException("Action has already executed");

}

//递归运行interceptor

if (interceptors.hasNext())

{          //interceptors是InterceptorMapping实际上是像一个像//FilterChain一样的Interceptor链

//通过调用Invocation.invoke()实现递归牡循环

final InterceptorMapping interceptor =
interceptors.next();

String interceptorMsg = "interceptor: " + interceptor.getName();

UtilTimerStack.push(interceptorMsg);

try {

//在每一个Interceptor的方法中都会return invocation.invoke()

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

}

finally {

UtilTimerStack.pop(interceptorMsg);

}

} else {

//当全部interceptor都运行完,最后运行Action,invokeActionOnly会调用//invokeAction()方法

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

//在Result返回之前调用preResultListeners

//通过executed控制,仅仅运行一次

if (!executed) {

if (preResultListeners !=
null) {

for (Object preResultListener :
preResultListeners) {

PreResultListener listener = (PreResultListener) preResultListener;

String _profileKey = "preResultListener: ";

try {

UtilTimerStack.push(_profileKey);

listener.beforeResult(this,
resultCode);

}

finally {

UtilTimerStack.pop(_profileKey);

}

}

}

// now execute the result, if we're supposed to

//运行result。

if (proxy.getExecuteResult()) {

executeResult();

}

executed = true;

}

return
resultCode;

}

finally {

UtilTimerStack.pop(profileKey);

}

}

最新文章

  1. 参数名ASCII码从小到大排序(字典序)
  2. [Java] final的意义
  3. c# 产生随机字符串,包括大小写字母和数字
  4. Android 使用XmlSerializer生成xml文件
  5. java.lang.String内部结构的变化
  6. Sonar入门(二): Maven集成Sonar
  7. php 文件操作类
  8. Spire.Office for .NET(Word、Excel、PPT、PDF等)
  9. 访问mysql出现“Access denied for user root@localhost”(using password:NO)解决方案
  10. LeadTools答题卡识别方案
  11. JAVA_SE基础——56.包的创建
  12. saltstack主机管理项目:主机管理项目需求分析(一)
  13. Linux常用系统命令
  14. python基础--概念性问题
  15. React中禁止chrome填充密码表单
  16. 浅谈react受控组件与非受控组件
  17. otunnel : 一个和lcx差不多的端口转发的工具
  18. CF878C Tournament set 图论
  19. MLlib1.6指南笔记
  20. mongodb 3.4复制集配置

热门文章

  1. AtCoder Grand Contest 021
  2. Convolutional Networks for Image Semantic Segmentation
  3. Js 希望某链接只能点击一次
  4. HDU——1020Encoding(水题,string过)
  5. 使用 SOAPUI 测试Web Service
  6. java 自定义log类
  7. C语言指针与数组
  8. 【HDOJ5971】Wrestling Match(二分图,并查集)
  9. 【NOIP2016练习】T2 旅行(树形DP,换根)
  10. C# 打印webBrowser打开的页面