前言:对于这部分的流程,网上已有很多文章进行描述,虽然不想重复造轮,但是为了能够加深自己对struts2的理解,还是有必要记录下这部分的执行流程,
其中有些部分会参考网络,只是为了便于学习,有不妥之处还请见谅。
本文章遵循下图的核心处理流程来进行阅读分析(参考网络):
ps:debug源码的前提,个人认为此图很好的反应了Interceptor和Action的执行流程。
FilterDispatcher:请求入口
/**
* 接收请求时,自动执行。
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
......
//得到存储Action信息的ActionMapping对象,将所有的拦截器及action进行全部执行
dispatcher.serviceAction(request, response, servletContext, mapping);
......
}
Dispatcher:FilterDispatcher交给Dispatcher的serviceAction执行
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
ActionMapping mapping) throws ServletException {
........
//1.获取初始化时的配置信息,具体不深究,反正是一些初始化信息,后面有用
Configuration config = configurationManager.getConfiguration();
//2.创建ActionProxy,ActionInvocation 返回DefaultActionProxy ,交给xwork进行一些Action代理类以及调度者的初始化工作
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, extraContext, true, false);
proxy.setMethod(method);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
//debug很多次,都为null,不知此处判断具体什么作用-mark!
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();//3.执行流程交给xwork执行
}
..........
}
ps:这里其实有很多实现问题都不清楚,网上也为此搜索了很多关于xwork的实现机制,例如Container,ContainerImpl等实现的机制,但是都没有太多的有价值的
文章或者帖子。先在这里mark下,当然也希望路过的牛人指点指点。
DefaultActionProxy类:
public String execute() throws Exception {
.....
retCode = invocation.invoke();//由调度者(DefaultActionInvocation)执行
......
return retCode;
}
DefaultActionInvocation类:
public String invoke() throws Exception { ......... if (interceptors.hasNext()) {//拦截器的递归调用和action的方法调用,当然针对自己定义的拦截器,是否递归调用取决于程序员本身。 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();//action的方法调用 } // 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); } }
为了更好的拦截器和action的执行流程,下面附图(参考网络):
![]()
总结:知识一开始或许都是模糊的,或许只有一个轮廓,但我相信这是你了解本质,掌握核心的必要前提。 有待了解: 1.xwork中的代理模式究竟如何实现? 2.xwork中的容器是如何实现? 3.或许还有很多。。。