接下来看看DefaultActionInvocation 的invoke方法。
- public void init(ActionProxy proxy) {
- this.proxy = proxy;
- Map contextMap = createContextMap();
- // Setting this so that other classes, like object factories, can use the ActionProxy and other
- // contextual information to operate
- ActionContext actionContext = ActionContext.getContext();
- if(actionContext != null) {
- actionContext.setActionInvocation(this);
- }
- //创建Action,可Struts2里是每次请求都新建一个Action
- createAction(contextMap);
- if (pushAction) {
- stack.push(action);
- contextMap.put("action", action);
- }
- invocationContext = new ActionContext(contextMap);
- invocationContext.setName(proxy.getActionName());
- // get a new List so we don't get problems with the iterator if someone changes the list
- List interceptorList = new ArrayList(proxy.getConfig().getInterceptors());
- interceptors = interceptorList.iterator();
- }
- protected void createAction(Map contextMap) {
- // load action
- String timerKey = "actionCreate: "+proxy.getActionName();
- try {
- UtilTimerStack.push(timerKey);
- //这儿默认建立Action是StrutsObjectFactory,实际中我使用的时候都是使用Spring创建的Action,这个时候使用的是SpringObjectFactory
- action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
- }
- ..
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- if (actionEventListener != null) {
- action = actionEventListener.prepare(action, stack);
- }
- }
- //接下来看看DefaultActionInvocation 的invoke方法。
- public String invoke() throws Exception {
- String profileKey = "invoke: ";
- try {
- UtilTimerStack.push(profileKey);
- if (executed) {
- throw new IllegalStateException("Action has already executed");
- }
- //先执行interceptors
- 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 {
- //interceptor执行完了之后执行action
- 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) {
- //在Result返回之前调用preResultListeners
- 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);
- }
- }
public void init(ActionProxy proxy) {
this.proxy = proxy;
Map contextMap = createContextMap();
// Setting this so that other classes, like object factories, can use the ActionProxy and other
// contextual information to operate
ActionContext actionContext = ActionContext.getContext();
if(actionContext != null) {
actionContext.setActionInvocation(this);
}
//创建Action,可Struts2里是每次请求都新建一个Action
createAction(contextMap);
if (pushAction) {
stack.push(action);
contextMap.put("action", action);
}
invocationContext = new ActionContext(contextMap);
invocationContext.setName(proxy.getActionName());
// get a new List so we don't get problems with the iterator if someone changes the list
List interceptorList = new ArrayList(proxy.getConfig().getInterceptors());
interceptors = interceptorList.iterator();
}
protected void createAction(Map contextMap) {
// load action
String timerKey = "actionCreate: "+proxy.getActionName();
try {
UtilTimerStack.push(timerKey);
//这儿默认建立Action是StrutsObjectFactory,实际中我使用的时候都是使用Spring创建的Action,这个时候使用的是SpringObjectFactory
action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
}
..
} finally {
UtilTimerStack.pop(timerKey);
}
if (actionEventListener != null) {
action = actionEventListener.prepare(action, stack);
}
}
//接下来看看DefaultActionInvocation 的invoke方法。
public String invoke() throws Exception {
String profileKey = "invoke: ";
try {
UtilTimerStack.push(profileKey);
if (executed) {
throw new IllegalStateException("Action has already executed");
}
//先执行interceptors
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 {
//interceptor执行完了之后执行action
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) {
//在Result返回之前调用preResultListeners
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);
}
}
看程序中的if(interceptors.hasNext())语句,当然,interceptors里存储的是interceptorMapping列表(它包括一个Interceptor和一个name),所有的截拦器必须实现Interceptor的intercept方法,而该方法的参数恰恰又是ActionInvocation,在intercept方法中还是调用invocation.invoke(),从而实现了一个Interceptor链的调用。当所有的Interceptor执行完,最后调用invokeActionOnly方法来执行Action相应的方法。
- protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
- String methodName = proxy.getMethod();
- String timerKey = "invokeAction: "+proxy.getActionName();
- try {
- UtilTimerStack.push(timerKey);
- boolean methodCalled = false;
- Object methodResult = null;
- Method method = null;
- try {
- //获得需要执行的方法
- method = getAction().getClass().getMethod(methodName, new Class[0]);
- } catch (NoSuchMethodException e) {
- //如果没有对应的方法,则使用do+Xxxx来再次获得方法
- try {
- String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
- method = getAction().getClass().getMethod(altMethodName, new Class[0]);
- } catch (NoSuchMethodException e1) {
- // well, give the unknown handler a shot
- if (unknownHandler != null) {
- try {
- methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);
- methodCalled = true;
- } catch (NoSuchMethodException e2) {
- // throw the original one
- throw e;
- }
- } else {
- throw e;
- }
- }
- }
- if (!methodCalled) {
- methodResult = method.invoke(action, new Object[0]);
- }
- //根据不同的Result类型返回不同值
- //如输出流Result
- if (methodResult instanceof Result) {
- this.explicitResult = (Result) methodResult;
- return null;
- } else {
- return (String) methodResult;
- }
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");
- } catch (InvocationTargetException e) {
- // We try to return the source exception.
- Throwable t = e.getTargetException();
- if (actionEventListener != null) {
- String result = actionEventListener.handleException(t, getStack());
- if (result != null) {
- return result;
- }
- }
- if (t instanceof Exception) {
- throw(Exception) t;
- } else {
- throw e;
- }
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
String methodName = proxy.getMethod();
String timerKey = "invokeAction: "+proxy.getActionName();
try {
UtilTimerStack.push(timerKey);
boolean methodCalled = false;
Object methodResult = null;
Method method = null;
try {
//获得需要执行的方法
method = getAction().getClass().getMethod(methodName, new Class[0]);
} catch (NoSuchMethodException e) {
//如果没有对应的方法,则使用do+Xxxx来再次获得方法
try {
String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
method = getAction().getClass().getMethod(altMethodName, new Class[0]);
} catch (NoSuchMethodException e1) {
// well, give the unknown handler a shot
if (unknownHandler != null) {
try {
methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);
methodCalled = true;
} catch (NoSuchMethodException e2) {
// throw the original one
throw e;
}
} else {
throw e;
}
}
}
if (!methodCalled) {
methodResult = method.invoke(action, new Object[0]);
}
//根据不同的Result类型返回不同值
//如输出流Result
if (methodResult instanceof Result) {
this.explicitResult = (Result) methodResult;
return null;
} else {
return (String) methodResult;
}
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");
} catch (InvocationTargetException e) {
// We try to return the source exception.
Throwable t = e.getTargetException();
if (actionEventListener != null) {
String result = actionEventListener.handleException(t, getStack());
if (result != null) {
return result;
}
}
if (t instanceof Exception) {
throw(Exception) t;
} else {
throw e;
}
} finally {
UtilTimerStack.pop(timerKey);
}
}
好了,action执行完了,还要根据ResultConfig返回到view,也就是在invoke方法中调用executeResult方法。
- private void executeResult() throws Exception {
- //根据ResultConfig创建Result
- result = createResult();
- String timerKey = "executeResult: "+getResultCode();
- try {
- UtilTimerStack.push(timerKey);
- if (result != null) {
- //这儿正式执行:)
- //可以参考Result的实现,如用了比较多的ServletDispatcherResult,ServletActionRedirectResult,ServletRedirectResult
- result.execute(this);
- } else if (resultCode != null && !Action.NONE.equals(resultCode)) {
- throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
- + " and result " + getResultCode(), proxy.getConfig());
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("No result returned for action "+getAction().getClass().getName()+" at "+proxy.getConfig().getLocation());
- }
- }
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
- public Result createResult() throws Exception {
- if (explicitResult != null) {
- Result ret = explicitResult;
- explicitResult = null;;
- return ret;
- }
- ActionConfig config = proxy.getConfig();
- Map results = config.getResults();
- ResultConfig resultConfig = null;
- synchronized (config) {
- try {
- //根据result名称获得ResultConfig,resultCode就是result的name
- resultConfig = (ResultConfig) results.get(resultCode);
- } catch (NullPointerException e) {
- }
- if (resultConfig == null) {
- //如果找不到对应name的ResultConfig,则使用name为*的Result
- resultConfig = (ResultConfig) results.get("*");
- }
- }
- if (resultConfig != null) {
- try {
- //参照StrutsObjectFactory的代码
- Result result = objectFactory.buildResult(resultConfig, invocationContext.getContextMap());
- return result;
- } catch (Exception e) {
- LOG.error("There was an exception while instantiating the result of type " + resultConfig.getClassName(), e);
- throw new XWorkException(e, resultConfig);
- }
- } else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandler != null) {
- return unknownHandler.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode);
- }
- return null;
- }
- //StrutsObjectFactory
- public Result buildResult(ResultConfig resultConfig, Map extraContext) throws Exception {
- String resultClassName = resultConfig.getClassName();
- if (resultClassName == null)
- return null;
- //创建Result,因为Result是有状态的,所以每次请求都新建一个
- Object result = buildBean(resultClassName, extraContext);
- //这句很重要,后面将会谈到,reflectionProvider参见OgnlReflectionProvider;
- //resultConfig.getParams()就是result配置文件里所配置的参数<param></param>
- //setProperties方法最终调用的是Ognl类的setValue方法
- //这句其实就是把param名值设置到根对象result上
- reflectionProvider.setProperties(resultConfig.getParams(), result, extraContext);
- if (result instanceof Result)
- return (Result) result;
- throw new ConfigurationException(result.getClass().getName() + " does not implement Result.");
- }
private void executeResult() throws Exception {
//根据ResultConfig创建Result
result = createResult();
String timerKey = "executeResult: "+getResultCode();
try {
UtilTimerStack.push(timerKey);
if (result != null) {
//这儿正式执行:)
//可以参考Result的实现,如用了比较多的ServletDispatcherResult,ServletActionRedirectResult,ServletRedirectResult
result.execute(this);
} else if (resultCode != null && !Action.NONE.equals(resultCode)) {
throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
+ " and result " + getResultCode(), proxy.getConfig());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("No result returned for action "+getAction().getClass().getName()+" at "+proxy.getConfig().getLocation());
}
}
} finally {
UtilTimerStack.pop(timerKey);
}
}
public Result createResult() throws Exception {
if (explicitResult != null) {
Result ret = explicitResult;
explicitResult = null;;
return ret;
}
ActionConfig config = proxy.getConfig();
Map results = config.getResults();
ResultConfig resultConfig = null;
synchronized (config) {
try {
//根据result名称获得ResultConfig,resultCode就是result的name
resultConfig = (ResultConfig) results.get(resultCode);
} catch (NullPointerException e) {
}
if (resultConfig == null) {
//如果找不到对应name的ResultConfig,则使用name为*的Result
resultConfig = (ResultConfig) results.get("*");
}
}
if (resultConfig != null) {
try {
//参照StrutsObjectFactory的代码
Result result = objectFactory.buildResult(resultConfig, invocationContext.getContextMap());
return result;
} catch (Exception e) {
LOG.error("There was an exception while instantiating the result of type " + resultConfig.getClassName(), e);
throw new XWorkException(e, resultConfig);
}
} else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandler != null) {
return unknownHandler.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode);
}
return null;
}
//StrutsObjectFactory
public Result buildResult(ResultConfig resultConfig, Map extraContext) throws Exception {
String resultClassName = resultConfig.getClassName();
if (resultClassName == null)
return null;
//创建Result,因为Result是有状态的,所以每次请求都新建一个
Object result = buildBean(resultClassName, extraContext);
//这句很重要,后面将会谈到,reflectionProvider参见OgnlReflectionProvider;
//resultConfig.getParams()就是result配置文件里所配置的参数<param></param>
//setProperties方法最终调用的是Ognl类的setValue方法
//这句其实就是把param名值设置到根对象result上
reflectionProvider.setProperties(resultConfig.getParams(), result, extraContext);
if (result instanceof Result)
return (Result) result;
throw new ConfigurationException(result.getClass().getName() + " does not implement Result.");
}
这样,一个Struts2的请求流程基本上就结束了。
转载于:https://blog.51cto.com/hongyanwb/625265