前言:对于这部分的流程,网上已有很多文章进行描述,虽然不想重复造轮,但是为了能够加深自己对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.或许还有很多。。。