Struts2源码阅读(六)_ActionProxy&ActionInvocation

下面开始讲一下主菜ActionProxy了.在这之前最好先去了解一下动态Proxy的基本知识.
ActionProxy是Action的一个 代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调 用了ActionInvocation.invoke()方法。归根到底,最后调用的是 DefaultActionInvocation.invokeAction()方法。
DefaultActionInvocation()->init()->createAction()。
最 后通过调用 ActionProxy.exute()-->ActionInvocation.invoke()-->Intercepter.intercept()-->ActionInvocation.invokeActionOnly()-->invokeAction()
这里的步骤是先由ActionProxyFactory创建ActionInvocation和ActionProxy.

1. public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) { 2. 3. ActionInvocation inv = new DefaultActionInvocation(extraContext, true); 4. container.inject(inv); 5. return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext); 6. }

 

先看DefaultActionInvocation的init方法

1. public void init(ActionProxy proxy) { 2. this.proxy = proxy; 3. Map contextMap = createContextMap(); 4. 5. // Setting this so that other classes, like object factories, can use the ActionProxy and other 6. // contextual information to operate 7. ActionContext actionContext = ActionContext.getContext(); 8. 9. if (actionContext != null) { 10. actionContext.setActionInvocation(this); 11. } 12. //创建Action,struts2中每一个Request都会创建一个新的Action 13. createAction(contextMap); 14. 15. if (pushAction) { 16. stack.push(action); 17. contextMap.put("action", action); 18. } 19. 20. invocationContext = new ActionContext(contextMap); 21. invocationContext.setName(proxy.getActionName()); 22. 23. // get a new List so we don't get problems with the iterator if someone changes the list 24. List interceptorList = new ArrayList(proxy.getConfig().getInterceptors()); 25. interceptors = interceptorList.iterator(); 26. } 27. 28. protected void createAction(Map contextMap) { 29. // load action 30. String timerKey = "actionCreate: " + proxy.getActionName(); 31. try { 32. UtilTimerStack.push(timerKey); 33. //默认为SpringObjectFactory:struts.objectFactory=spring.这里非常巧妙,在struts.properties中可以重写这个属性 34. //在前面BeanSelectionProvider中通过配置文件为ObjectFactory设置实现类 35. //这里以Spring为例,这里会调到SpringObjectFactory的buildBean方法,可以通过ApplicationContext的getBean()方法得到Spring的Bean 36. action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap); 37. } catch (InstantiationException e) { 38. throw new XWorkException("Unable to intantiate Action!", e, proxy.getConfig()); 39. } catch (IllegalAccessException e) { 40. throw new XWorkException("Illegal access to constructor, is it public?", e, proxy.getConfig()); 41. } catch (Exception e) { 42. ... 43. } finally { 44. UtilTimerStack.pop(timerKey); 45. } 46. 47. if (actionEventListener != null) { 48. action = actionEventListener.prepare(action, stack); 49. } 50. } 51. //SpringObjectFactory 52. public Object buildBean(String beanName, Map extraContext, boolean injectInternal) throws Exception { 53. Object o = null; 54. try { 55. //SpringObjectFactory会通过web.xml中的context-param:contextConfigLocation自动注入ClassPathXmlApplicationContext 56. o = appContext.getBean(beanName); 57. } catch (NoSuchBeanDefinitionException e) { 58. Class beanClazz = getClassInstance(beanName); 59. o = buildBean(beanClazz, extraContext); 60. } 61. if (injectInternal) { 62. injectInternalBeans(o); 63. } 64. return o; 65. }

 

1. //接下来看看DefaultActionInvocation 的invoke方法 2. public String invoke() throws Exception { 3. String profileKey = "invoke: "; 4. try { 5. UtilTimerStack.push(profileKey); 6. 7. if (executed) { 8. throw new IllegalStateException("Action has already executed"); 9. } 10. //递归执行interceptor 11. if (interceptors.hasNext()) { 12. //interceptors是InterceptorMapping实际上是像一个像FilterChain一样的Interceptor链 13. //通过调用Invocation.invoke()实现递归牡循环 14. final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); 15. String interceptorMsg = "interceptor: " + interceptor.getName(); 16. UtilTimerStack.push(interceptorMsg); 17. try { 18. //在每个Interceptor的方法中都会return invocation.invoke() 19. resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); 20. } 21. finally { 22. UtilTimerStack.pop(interceptorMsg); 23. } 24. } else { 25. //当所有interceptor都执行完,最后执行Action,invokeActionOnly会调用invokeAction()方法 26. resultCode = invokeActionOnly(); 27. } 28. 29. // this is needed because the result will be executed, then control will return to the Interceptor, which will 30. // return above and flow through again 31. //在Result返回之前调用preResultListeners 32. //通过executed控制,只执行一次 33. if (!executed) { 34. if (preResultListeners != null) { 35. for (Object preResultListener : preResultListeners) { 36. PreResultListener listener = (PreResultListener) preResultListener; 37. 38. String _profileKey = "preResultListener: "; 39. try { 40. UtilTimerStack.push(_profileKey); 41. listener.beforeResult(this, resultCode); 42. } 43. finally { 44. UtilTimerStack.pop(_profileKey); 45. } 46. } 47. } 48. 49. // now execute the result, if we're supposed to 50. //执行Result 51. if (proxy.getExecuteResult()) { 52. executeResult(); 53. } 54. 55. executed = true; 56. } 57. 58. return resultCode; 59. } 60. finally { 61. UtilTimerStack.pop(profileKey); 62. } 63. } 64. 65. //invokeAction 66. protected String invokeAction(Object action,ActionConfig actionConfig)throws Exception{ 67. String methodName = proxy.getMethod(); 68. 69. String timerKey = "invokeAction: " + proxy.getActionName(); 70. try { 71. UtilTimerStack.push(timerKey); 72. 73. boolean methodCalled = false; 74. Object methodResult = null; 75. Method method = null; 76. try { 77. //java反射机制得到要执行的方法 78. method = getAction().getClass().getMethod(methodName, new Class[0]); 79. } catch (NoSuchMethodException e) { 80. // hmm -- OK, try doXxx instead 81. //如果没有对应的方法,则使用do+Xxxx来再次获得方法 82. try { 83. String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1); 84. method = getAction().getClass().getMethod(altMethodName, new Class[0]); 85. } catch (NoSuchMethodException e1) { 86. // well, give the unknown handler a shot 87. if (unknownHandlerManager.hasUnknownHandlers()) { 88. try { 89. methodResult = unknownHandlerManager.handleUnknownMethod(action, methodName); 90. methodCalled = true; 91. } catch (NoSuchMethodException e2) { 92. // throw the original one 93. throw e; 94. } 95. } else { 96. throw e; 97. } 98. } 99. } 100. //执行Method 101. if (!methodCalled) { 102. methodResult = method.invoke(action, new Object[0]); 103. } 104. //从这里可以看出可以Action的方法可以返回String去匹配Result,也可以直接返回Result类 105. if (methodResult instanceof Result) { 106. this.explicitResult = (Result) methodResult; 107. 108. // Wire the result automatically 109. container.inject(explicitResult); 110. return null; 111. } else { 112. return (String) methodResult; 113. } 114. } catch (NoSuchMethodException e) { 115. throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + ""); 116. } catch (InvocationTargetException e) { 117. // We try to return the source exception. 118. Throwable t = e.getTargetException(); 119. 120. if (actionEventListener != null) { 121. String result = actionEventListener.handleException(t, getStack()); 122. if (result != null) { 123. return result; 124. } 125. } 126. if (t instanceof Exception) { 127. throw (Exception) t; 128. } else { 129. throw e; 130. } 131. } finally { 132. UtilTimerStack.pop(timerKey); 133. } 134. }

 

action执行完了,还要根据ResultConfig返回到view,也就是在invoke方法中调用executeResult方法。

1. private void executeResult() throws Exception { 2. //根据ResultConfig创建Result 3. result = createResult(); 4. 5. String timerKey = "executeResult: " + getResultCode(); 6. try { 7. UtilTimerStack.push(timerKey); 8. if (result != null) { 9. //开始执行Result, 10. //可以参考Result的实现,如用了比较多的ServletDispatcherResult,ServletActionRedirectResult,ServletRedirectResult 11. result.execute(this); 12. } else if (resultCode != null && !Action.NONE.equals(resultCode)) { 13. throw new ConfigurationException("No result defined for action " + getAction().getClass().getName() 14. + " and result " + getResultCode(), proxy.getConfig()); 15. } else { 16. if (LOG.isDebugEnabled()) { 17. LOG.debug("No result returned for action " + getAction().getClass().getName() + " at " + proxy.getConfig().getLocation()); 18. } 19. } 20. } finally { 21. UtilTimerStack.pop(timerKey); 22. } 23. } 24. 25. public Result createResult() throws Exception { 26. //如果Action中直接返回的Result类型,在invokeAction()保存在explicitResult 27. if (explicitResult != null) { 28. Result ret = explicitResult; 29. explicitResult = null; 30. 31. return ret; 32. } 33. //返回的是String则从config中得到当前Action的Results列表 34. ActionConfig config = proxy.getConfig(); 35. Map results = config.getResults(); 36. 37. ResultConfig resultConfig = null; 38. 39. synchronized (config) { 40. try { 41. //通过返回的String来匹配resultConfig 42. resultConfig = results.get(resultCode); 43. } catch (NullPointerException e) { 44. // swallow 45. } 46. if (resultConfig == null) { 47. // If no result is found for the given resultCode, try to get a wildcard '*' match. 48. //如果找不到对应name的ResultConfig,则使用name为*的Result 49. //说明可以用*通配所有的Result 50. resultConfig = results.get("*"); 51. } 52. } 53. 54. if (resultConfig != null) { 55. try { 56. //创建Result 57. return objectFactory.buildResult(resultConfig, invocationContext.getContextMap()); 58. } catch (Exception e) { 59. LOG.error("There was an exception while instantiating the result of type " + resultConfig.getClassName(), e); 60. throw new XWorkException(e, resultConfig); 61. } 62. } else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandlerManager.hasUnknownHandlers()) { 63. return unknownHandlerManager.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode); 64. } 65. return null; 66. } 67. 68. public Result buildResult(ResultConfig resultConfig, Map extraContext) throws Exception { 69. String resultClassName = resultConfig.getClassName(); 70. Result result = null; 71. 72. if (resultClassName != null) { 73. //buildBean中会用反射机制Class.newInstance来创建bean 74. result = (Result) buildBean(resultClassName, extraContext); 75. Map params = resultConfig.getParams(); 76. if (params != null) { 77. for (Map.Entry paramEntry : params.entrySet()) { 78. try { 79. //reflectionProvider参见OgnlReflectionProvider; 80. //resultConfig.getParams()就是result配置文件里所配置的参数 81. //setProperties方法最终调用的是Ognl类的setValue方法 82. //这句其实就是把param名值设置到根对象result上 83. reflectionProvider.setProperty(paramEntry.getKey(), paramEntry.getValue(), result, extraContext, true); 84. } catch (ReflectionException ex) { 85. if (LOG.isErrorEnabled()) 86. LOG.error("Unable to set parameter [#0] in result of type [#1]", ex, 87. paramEntry.getKey(), resultConfig.getClassName()); 88. if (result instanceof ReflectionExceptionHandler) { 89. ((ReflectionExceptionHandler) result).handle(ex); 90. } 91. } 92. } 93. } 94. } 95. 96. return result; 97. }

 

http://qidaoxp.javaeye.com/blog/503015

你可能感兴趣的:(Struts,struts,interceptor,action,exception,string,null)