Struts2源码阅读之Action和Interceptor的执行流程

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










  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值