`
TechBirds
  • 浏览: 82056 次
文章分类
社区版块
存档分类
最新评论

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.或许还有很多。。。











分享到:
评论

相关推荐

    Struts2演示源码

    该代码演示了Action中result的四种转发类型、多文件上传、自定义拦截器、对Action中方法进行输入校验以及OGNL表达式等内容。

    Struts 2.1.8_学习源码

    Struts2_04ActionResultType : Struts2关于Action跳转类型的应用 对各种不同的跳转类型使用的实例 Struts2_05Interceptor : Struts2拦截器的使用 Struts2_06FileUpload : Struts2上传文件的使用

    Struts2入门教程(全新完整版)

    一、准备工作及实例 3 1.解压struts-2.1.6-all.zip 3 2.六个基本包 3 3.初识struts2配置文件 4 ... 下面对struts2的基本执行流程作一简要说明,此流程说明可以结合官方提供的struts2结构图来看: 60

    Struts拦截器及token拦截器防止重复提交例子源码

    其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。 intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。

    深入浅出Struts2(附源码)

    作者处处从实战出发,在丰富的示例中直观地探讨了许多实用的技术,如数据类型转换、文件上传和下载、提高Struts 2应用的安全性、调试与性能分析、FreeMarker、Velocity、Ajax,等等。跟随作者一道深入Struts 2,聆听...

    名为责任链或者拦截器或者过滤器的简单模拟

    比如说,struts2中Action在执行之前会首先执行一些Interceptor,完成诸如权限验证/属性注入/Validation/国际化等等的功能, 我看过一个比较好的功能是,利用strut2的拦截器和*-Validation.xml文件以及标签(strut2...

    当当网全套源码(附带邮箱验证功能)

    控制层:Struts2控制器组件、Action组件 c.业务层:Bean组件 d.数据访问层:DAO组件(JDBC) 4.数据库设计 1)数据库导入 create database dangdang; //创建库 use dangdang; //进入dangdang库 set names utf8;...

    java后台框架源码

    action:存放struts2控制类的包 dao:数据库访问封装 enm:系统中使用到的常量包,这里不是用的常量,用的是枚举替代常量 entity:hibernate对应的orm与数据库表一一对应的实体类 filter:Log4jFormatFilter(格式化...

    房屋中介的系统

    (2)业务方面:建了vo,util工具,dao各种方法,service,action,interceptor拦截器,这些层。 (3)配置方面:struts.xml reg-validator hbm.xml log4j.properties web.xml (4)web方面:css样式,前台的注册和登录...

    ssh(structs,spring,hibernate)框架中的上传下载

    Struts+Spring+Hibernate实现上传下载    本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本:  •Struts 1.2  •Spring 1.2.5  •Hibernate 3.0  本文...

Global site tag (gtag.js) - Google Analytics