DefaultActionInvocation类的执行action
本章简言 |
上一章讲到关于拦截器的机制的知识点,让我们对拦截器有了一定的认识。我们也清楚的知道在执行用户action类实例之前,struts2会先去执行当前action类对应的拦截器。而关于在哪里执行action类实例,笔者根本就没有详细的讲到。更多只是几笔带过而以。虽然在《Struts2 源码分析——Action代理类的工作》章节里面也讲到过关于DefaultActionInvocation类的一些作用。提过DefaultActionInvocation类会去执行action类实例。但是还是没有具体的指出重点的代码。而本章就是来讲执行action类实例的代码落在哪里。即是DefaultActionInvocation类的invokeAction方法。
成都创新互联公司网站建设提供从项目策划、软件开发,软件安全维护、网站优化(SEO)、网站分析、效果评估等整套的建站服务,主营业务为做网站、成都做网站,成都app开发以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。成都创新互联公司深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
DefaultActionInvocation类的执行action |
上一章里面有提到过DefaultActionInvocation类的invoke方法里面的invokeActionOnly方法。没有错!当所有拦截器前半部分执行结束之后,就会去执行invokeActionOnly方法。这个方法就是执行action类实例的入口。而invokeActionOnly方法实际是去调用本身类的invokeAction方法。看一下代码就知道了。
DefaultActionInvocation类:
1 public String invokeActionOnly() throws Exception {2 return invokeAction(getAction(), proxy.getConfig());3 }
代码里面getAction方法就是获得action类实例。即是跟《Struts2 源码分析——Action代理类的工作》章节里面讲到的createAction方法有关。当程序执行到这里的时候,createAction方法已经新建好了action类实例。不清楚读者请到这章去看一下。让我们看一下invokeAction方法的源码吧。
1 protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception { 2 String methodName = proxy.getMethod();//获得要执行的方法名。 3 4 LOG.debug("Executing action method = {}", methodName); 5 6 String timerKey = "invokeAction: " + proxy.getActionName(); 7 try { 8 UtilTimerStack.push(timerKey); 9 10 Object methodResult;11 try {12 methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action);//执行action类实例13 } catch (MethodFailedException e) {14 // if reason is missing method, try checking UnknownHandlers15 if (e.getReason() instanceof NoSuchMethodException) {16 if (unknownHandlerManager.hasUnknownHandlers()) {17 try {18 methodResult = unknownHandlerManager.handleUnknownMethod(action, methodName);19 } catch (NoSuchMethodException ignore) {20 // throw the original one21 throw e;22 }23 } else {24 // throw the original one25 throw e;26 }27 // throw the original exception as UnknownHandlers weren't able to handle invocation as well28 if (methodResult == null) {29 throw e;30 }31 } else {32 // exception isn't related to missing action method, throw it33 throw e;34 }35 }36 return saveResult(actionConfig, methodResult);37 } catch (NoSuchPropertyException e) {38 throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");39 } catch (MethodFailedException e) {40 // We try to return the source exception.41 Throwable t = e.getCause();42 43 if (actionEventListener != null) {44 String result = actionEventListener.handleException(t, getStack());45 if (result != null) {46 return result;47 }48 }49 if (t instanceof Exception) {50 throw (Exception) t;51 } else {52 throw e;53 }54 } finally {55 UtilTimerStack.pop(timerKey);56 }57 }
这个方法的做的事情是很简单。就是获得当前action类实例要执行的方法名。在根据OgnlUtil工具类在执行对应action类实例的方法。显然想要知道更深一点的话就必须深入OgnlUtil工具类的源码。让我们看一下吧。
OgnlUtil类:
1 public Object callMethod(final String name, final Mapcontext, final Object root) throws OgnlException {2 return compileAndExecuteMethod(name, context, new OgnlTask